Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
NEXTCLOUD_URLYesThe URL of your Nextcloud instance (e.g., https://your-nextcloud.example.com)
NEXTCLOUD_USERYesYour Nextcloud username
NEXTCLOUD_PASSWORDYesYour Nextcloud app password (not your main password)
NEXTCLOUD_MCP_RETRY_MAXNoMaximum retries on 429/503 errors (0 to disable)3
NEXTCLOUD_MCP_PERMISSIONSNoPermission level: read, write, or destructiveread
NEXTCLOUD_MCP_UPLOAD_ROOTNoAbsolute directory path to enable upload_file_from_path tool. Files must reside inside this directory.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
get_activityA

Get the recent activity feed for the current Nextcloud user.

Activities track what happened across Nextcloud: file changes, shares, calendar events, comments, and more.

Filters include "all", "self" (your actions), "by" (others' actions), "files", "files_sharing", "files_favorites", "calendar", "comments" and more, depending on the installed apps; list_activity_filters lists them.

To get activities for a specific file or object, provide both object_type and object_id (e.g., object_type="files", object_id=742), and leave activity_filter at "all". This also clears the returned activities' notifications, as the web interface does when it shows a file's activity.

Args: activity_filter: Activity filter id (default: "all"). limit: Maximum number of activities to return (1-200, default: 30). since: Activity ID to paginate from. Use the "since" value from the previous call's pagination to fetch the next page. Default 0 = newest. object_type: Filter by object type (e.g., "files"). Must be used together with object_id. object_id: Filter by object ID. Must be used together with object_type. sort: Sort order: "desc" (newest first, default) or "asc" (oldest first). search: Only activities whose file path contains this text (2-255 characters after trimming, case-insensitive), which leaves out activities without a file. start: Only activities at or after this time: an ISO 8601 date (from its start, UTC) or a time with a time zone. end: Only activities at or before this time: an ISO 8601 date (to its end, UTC) or a time with a time zone. actor: Only activities done by this user ID. search, start, end and actor need Nextcloud 35 (Activity 8); on older servers they are refused rather than ignored.

Returns: JSON object with "data" (list of activities) and "pagination" (count, has_more, since). Use since value for the next page.

list_activity_filtersA

List the activity filters get_activity accepts on this server.

Returns: JSON list of filters with "id" (the value for activity_filter) and "name".

get_activity_countsA

Count the current user's activities per day over the last days, e.g. to see when something happened.

Needs Nextcloud 35 (Activity 8). Days are the user's days in their Nextcloud time zone, ending today, while a date passed to get_activity's start and end is a UTC day; to list one of these days, pass start and end as times with the user's UTC offset (e.g. 2026-09-20T00:00:00+02:00 and 2026-09-20T23:59:59+02:00).

Args: activity_filter: Activity filter id (default: "all"); see list_activity_filters. days: Number of days ending today (1-366, default 30). search: Only count activities whose file path contains this text (2-255 characters). actor: Only count activities done by this user ID. object_type: Only count activities about this object; must be used together with object_id, and with activity_filter left at "all". object_id: The object's ID, e.g. a file ID for object_type "files".

Returns: JSON object with "from" and "to" (dates), "counts" (date to count, only days with activity), "total" and "max". "partial_before" is set when Nextcloud stopped counting at its row limit: counts for that date and earlier are missing, so a shorter window gives complete numbers.

list_announcementsA

List announcements from the Nextcloud Announcement Center.

Returns announcements visible to the current user, sorted by newest first. The server returns up to 7 announcements per page.

Admins see all announcements. Regular users only see announcements targeted at their groups or at "everyone".

Args: offset: Announcement ID to paginate from. Pass the smallest ID from a previous call to fetch older announcements. Default 0 means start from the newest.

Returns: JSON object with "data" (list of announcements) and "pagination" (count, offset, has_more). Each announcement has: id, author_id, author, time (unix), subject, message (markdown), groups (admin only), comments (count or false if disabled).

create_announcementA

Create a new announcement in Nextcloud. Requires admin privileges.

Announcements are posted to the Announcement Center and optionally trigger activity entries, notifications, and/or emails for the targeted groups.

Args: subject: Announcement title (1-512 characters, required). message: Announcement body in Markdown format. plain_message: Plain text version of the body. If empty, the markdown message is used as fallback. groups: List of group IDs to target (e.g. ["admin", "staff"]). Default: ["everyone"] (visible to all users). activities: Post to the activity stream (default: true). notifications: Send in-app notifications (default: true). emails: Send email notifications (default: false). comments: Allow comments on this announcement (default: true).

Returns: JSON object with the created announcement details.

delete_announcementA

Delete an announcement from Nextcloud. Requires admin privileges.

This permanently removes the announcement and all associated comments and notifications. This action is irreversible.

Args: announcement_id: The numeric announcement ID. Use list_announcements to find IDs.

Returns: Confirmation message.

list_appsA

List installed Nextcloud apps. Requires admin privileges.

Args: app_filter: Filter apps by status. Options: "enabled" (default) — only enabled apps "disabled" — only disabled apps "all" — all installed apps limit: Maximum number of apps to return (1-500, default 50). offset: Number of apps to skip for pagination (default 0).

Returns: JSON with "data" (list of app ID strings) and "pagination" (count, offset, limit, has_more).

get_app_infoA

Get detailed information about an installed Nextcloud app. Requires admin privileges.

Returns app metadata including name, version, description, and author.

Args: app_id: The app identifier (e.g. "spreed", "mail", "collectives"). Use list_apps to find available app IDs.

Returns: JSON object with app details: id, name, summary, version, author.

enable_appA

Enable a Nextcloud app. Requires admin privileges.

Activates a previously disabled or newly installed app. This makes the app's features available to users.

Args: app_id: The app identifier to enable (e.g. "spreed", "mail").

Returns: Confirmation message.

disable_appA

Disable a Nextcloud app. Requires admin privileges.

Deactivates the app, making its features unavailable. The app data is preserved and can be re-enabled later.

Be careful: disabling core apps (like files, dav) can break Nextcloud functionality.

Args: app_id: The app identifier to disable (e.g. "weather_status").

Returns: Confirmation message.

list_calendarsA

List all calendars for the current user.

Returns calendars with their properties including name, color, supported component types (VEVENT, VTODO), and write access status.

Returns: JSON list of calendar objects with: id, name, color, components, writable, ctag. Use the id value with other calendar tools (e.g. "personal").

get_eventsA

Get events from a calendar, optionally filtered by time range.

Without start/end, returns all events in the calendar. With start and end, returns only events overlapping that range (including recurring event instances).

Args: calendar_id: Calendar identifier (default "personal"). Use list_calendars to find IDs. start: Optional range start in ISO 8601 UTC format: "2026-04-01T00:00:00Z". Required if end is provided. end: Optional range end in ISO 8601 UTC format: "2026-04-30T23:59:59Z". Required if start is provided. limit: Maximum number of events to return (1-500, default 50). offset: Number of events to skip for pagination (default 0).

Returns: JSON with "data" (list of event objects) and "pagination" (count, offset, limit, has_more).

get_eventA

Get full details of a specific calendar event by its UID.

Args: calendar_id: Calendar identifier (e.g. "personal"). event_uid: The event's UID. Use get_events to find UIDs.

Returns: JSON object with full event details: uid, summary, dtstart, dtend, description, location, status, all_day, etag, and optionally rrule, categories.

create_eventA

Create a new calendar event.

Args: calendar_id: Calendar identifier (e.g. "personal"). summary: Event title/summary. start: Start date or datetime in ISO 8601 format. For timed events: "2026-04-01T10:00:00Z" or "2026-04-01T10:00:00". For all-day events: "2026-04-01". end: End date or datetime. Optional — defaults to 1 hour after start for timed events, or next day for all-day events. all_day: Set to true for an all-day event. When true, start/end are dates only. description: Optional event description/notes. location: Optional event location. status: Event status: "CONFIRMED" (default), "TENTATIVE", or "CANCELLED". categories: Optional comma-separated category names (e.g. "Work,Meeting"). rrule: Optional recurrence rule in iCalendar RRULE format. Examples: "FREQ=DAILY;COUNT=5", "FREQ=WEEKLY;BYDAY=MO,WE,FR", "FREQ=MONTHLY;BYMONTHDAY=15;UNTIL=20261231T235959Z".

Returns: JSON object with the created event's uid and summary.

update_eventA

Update an existing calendar event. Only provided fields are changed.

Uses the event's ETag for safe concurrent updates — if the event was modified since it was last read, the update will fail with a conflict error.

Args: calendar_id: Calendar identifier (e.g. "personal"). event_uid: The event's UID to update. Use get_events to find UIDs. summary: New event title. start: New start date/datetime in ISO 8601 format. end: New end date/datetime in ISO 8601 format. description: New description. Pass "" to clear. location: New location. Pass "" to clear. status: New status: "CONFIRMED", "TENTATIVE", or "CANCELLED". categories: New categories as comma-separated string. Pass "" to clear.

Returns: Confirmation message with the updated event UID.

delete_eventA

Delete a calendar event by its UID.

The event is moved to the calendar trashbin and can be restored from the Nextcloud web interface within the retention period.

Args: calendar_id: Calendar identifier (e.g. "personal"). event_uid: The event's UID to delete. Use get_events to find UIDs.

Returns: Confirmation message.

list_circlesA

List circles (teams) the current user can see.

Args: limit: Max circles to return. Omit for server default (all). offset: Starting offset for pagination.

Returns: JSON array of circles. Each entry includes id (the string singleId used for sharing), name, displayName, description, config (bitmask), source, population, creation, initiator (current-user membership info: level, status, userId).

get_circleA

Get full details of a circle including the current user's membership info.

Args: circle_id: String circle id (the hash from list_circles, e.g. "cUXI7OgXkF6u5jWUoE73AtmyjVE2ZRl").

Returns: JSON object with the circle's name, description, config, settings, source, population, creation timestamp, and initiator object describing the current user's membership (id, singleId, level, status, userId).

list_circle_membersA

List all members of a circle.

Args: circle_id: String circle id. full_details: If True, include extended info such as circle memberships inherited through this one.

Returns: JSON array of members. Each entry has id (memberId — use with remove_circle_member and update_circle_member_level), singleId (the user's federated id), userId, userType (1=user, 2=group, 4=mail, 8=contact, 16=circle), level (0=none, 1=member, 4=moderator, 8=admin, 9=owner), status ("Member", "Invited", "Requesting"), displayName, instance.

search_circlesA

Search for circles and potential members (users, groups, emails) by term.

Args: term: Search phrase. Matches against names/ids.

Returns: JSON array of search results. Each entry includes id (the singleId for users/groups/circles), userId, displayName, instance, and userType (1=user, 2=group, 4=mail, 8=contact, 16=circle).

create_circleA

Create a new circle (team).

Args: name: Display name of the new circle. Does not have to be unique. personal: If True, create a personal circle visible only to the owner (useful for private contact groups). local: If True, mark the circle as local (not federated to other instances) even when global scope is enabled. team_folder: If True, also create a team folder: a shared folder every member sees in Files, named after the team (with a number added when that name is taken; see its mountPoint). Needs Nextcloud 35 or later with the Team folders app. Deleting the team later deletes the folder and its files too.

Returns: JSON of the new circle including its generated id. The caller is automatically added as owner (level=9). With team_folder, it also has team_folder (id, mountPoint, quota) or null with team_folder_note saying why none was created.

update_circle_nameA

Rename a circle. Requires admin or owner level on the circle.

Args: circle_id: String circle id. name: New name.

Returns: JSON of the updated circle.

update_circle_descriptionA

Update a circle's description. Requires admin or owner level.

Args: circle_id: String circle id. description: New description text. Pass empty string to clear.

Returns: JSON of the updated circle.

update_circle_configA

Update a circle's config flags (bitmask). Requires admin or owner level.

The server auto-adjusts dependent flags — inspect the config field of the returned circle to see what was actually stored:

  • Setting REQUEST (64) without OPEN auto-adds OPEN → stored as 80.

  • Setting FEDERATED (32768) without ROOT auto-adds ROOT → stored as 40960.

  • Clearing OPEN while REQUEST is on drops REQUEST too.

  • Clearing ROOT while FEDERATED is on drops FEDERATED too.

Args: circle_id: String circle id. config: Bitmask integer. Valid user-facing flags (combine with OR): 8=VISIBLE (listed for non-members), 16=OPEN (anyone can join via join_circle), 32=INVITE (adding a member generates an invitation to accept), 64=REQUEST (join requests need moderator approval; implies OPEN), 128=FRIEND (members can invite friends), 256=PROTECTED (password-protected; password must be set via a dedicated setting endpoint, not exposed by this tool), 4096=LOCAL (not federated, even on GlobalScale), 8192=ROOT (circle cannot be nested inside another circle), 16384=CIRCLE_INVITE (nested circles confirm before joining), 32768=FEDERATED (federated to other instances; implies ROOT), 65536=MOUNTPOINT (auto-create Files folder). Pass 0 for a fully private, invite-by-admin-only circle. NOTE: 1 (SINGLE), 2 (PERSONAL), 4 (SYSTEM), 512 (NO_OWNER), 1024 (HIDDEN), 2048 (BACKEND), and 131072 (APP) are rejected by the public API (400 "Configuration value is not valid").

Returns: JSON of the updated circle. Compare config in the response to the requested value to detect auto-mutations described above.

join_circleA

Join an open circle on behalf of the current user.

The circle must have the OPEN config flag (16); otherwise the server returns an error. For invitation-only circles, the circle's admin or moderator must use add_circle_member instead.

Args: circle_id: String circle id.

Returns: JSON of the current user's new membership (id, level, status).

leave_circleA

Leave a circle the current user is a member of.

IMPORTANT: When the owner leaves, the server makes another member the owner (the highest level, then the longest-standing). Any entry of list_circle_members counts, even a group, a nested circle or a pending invitation or join request. When the owner is the last one, leaving destroys the entire circle, with no confirmation prompt. Because of this implicit destroy, this tool requires DESTRUCTIVE permission (matching leave_conversation in Talk).

Args: circle_id: String circle id. delete_team_folder: Destroying the circle also deletes its team folder (Nextcloud 35+ with the Team folders app) and every file in it. When that would happen, the tool refuses unless this is true.

Returns: JSON of the circle the user just left (circle fields: id, name, config, population, initiator, …). Empty when the caller loses visibility on the circle after leaving (e.g. when the circle is destroyed).

add_circle_memberA

Add a user, group, email, or nested circle as a member. Requires moderator+.

Args: circle_id: String circle id. user_id: The identifier of the principal being added. For user: the uid. For group: the group id. For mail: the email address. For circle: the string circle id (singleId). member_type: One of "user" (default), "group", "mail", "contact", "circle". Determines how user_id is interpreted.

Returns: JSON of the new member (id, singleId, userId, level, status). Status is "Member" for direct add and "Invited" when the circle has the INVITE config flag set.

update_circle_member_levelA

Change a member's level (role) in the circle. Requires admin or owner.

Args: circle_id: String circle id. member_id: The member-level id from list_circle_members (NOT the user's singleId or userId — use the "id" field from members). level: One of "member", "moderator", "admin", "owner". Promoting someone to "owner" transfers ownership; the caller becomes admin. Older Circles releases cannot transfer ownership on SQLite or PostgreSQL; the tool then says so and nothing changes.

Returns: JSON of the updated member (same shape as entries from list_circle_members: id, userId, level, status, circleId, singleId, …). Use the "level" field to confirm the new role. Note: this returns the member, not the circle.

delete_circleA

Delete a circle. Requires owner level. Removes all memberships.

Args: circle_id: String circle id. delete_team_folder: Deleting a circle also deletes its team folder (Nextcloud 35+ with the Team folders app) and every file in it, for all members, also when it is an older group folder an admin linked to the team. If the circle has one, the tool refuses unless this is true.

Returns: Confirmation with the deleted id, and deleted_team_folder (the folder's name) when a team folder goes with it. Circles finishes the deletion in the background within seconds.

remove_circle_memberA

Kick a member out of a circle. Requires moderator+. Cannot remove the owner.

Args: circle_id: String circle id. member_id: The id from list_circle_members (not the userId).

Returns: Confirmation with the removed member id.

list_collectivesA

List collectives the current user has access to.

Collectives are shared knowledge bases with wiki-style pages.

Args: limit: Maximum number of collectives to return (1-200, default 50). offset: Number of collectives to skip for pagination (default 0).

Returns: JSON with "data" (list of collectives with id, name, emoji, permissions) and "pagination" (count, offset, limit, has_more).

get_collective_pagesA

List pages in a collective.

Returns the page tree including the landing page and all subpages.

Args: collective_id: The numeric collective ID. Use list_collectives to find IDs. limit: Maximum number of pages to return (1-200, default 50). offset: Number of pages to skip for pagination (default 0).

Returns: JSON with "data" (list of pages with id, title, emoji, timestamp, size) and "pagination" (count, offset, limit, has_more). Page text is not included here; read one page with get_collective_page to get it.

get_collective_pageA

Get a single page from a collective, including its content.

Collectives serves page metadata and page text from two different places, so this reads the page's Markdown file after the metadata call.

Args: collective_id: The numeric collective ID. page_id: The numeric page ID. Use get_collective_pages to find IDs.

Returns: JSON object with page details and "content", the page's Markdown text. An empty page has an empty string. When the file cannot be read, "content" is null and "content_error" says why.

search_collective_pagesA

Search the text of a collective's pages.

Uses Collectives' search index, which a background job keeps up to date, so pages written in the last few minutes may not be found yet. For titles, get_collective_pages lists every page.

Args: collective_id: The numeric collective ID. query: Words to look for.

Returns: JSON list of matching pages (id, title, parent_id, emoji, timestamp, ...).

list_recent_collective_pagesA

List the most recently changed pages across all your collectives, newest first.

Changes by anyone count; visits do not.

Args: query: Only pages whose title contains this (default: all). limit: Maximum pages (1-100, default 10).

Returns: JSON list of pages with id, title, collective (its name) and collective_id (null for a collective whose name has no letters or digits), plus the usual page fields.

create_collectiveA

Create a new collective (shared knowledge base).

A collective is a wiki-like space where team members can create and edit pages together. It automatically creates a landing page, and a team (circle) of the same name for its members. On Nextcloud 35+ with the Team folders app, that team also gets a team folder.

Args: name: Name of the collective (required, must be unique). emoji: Optional emoji icon for the collective (e.g. "📚").

Returns: JSON object with the created collective details, and team_folder (the folder's name) when its team got one.

create_collective_pageA

Create a new page in a collective.

Pages are Markdown documents organized in a tree structure. Every page must have a parent — use the landing page ID as parent for top-level pages.

Args: collective_id: The numeric collective ID. parent_id: Parent page ID. Use the landing page ID from get_collective_pages for top-level pages. title: Title of the new page (required). content: Optional Markdown text for the page.

Returns: JSON object with the created page details.

update_collective_pageA

Change a page's text, title or emoji. Only what you pass changes.

The text replaces the whole page; read it first with get_collective_page to edit part of it. Earlier versions stay in the file's version history. Someone editing the page in the browser at the same time may be asked which version to keep.

Args: collective_id: The numeric collective ID. page_id: The numeric page ID. content: New Markdown text for the whole page. title: New title (renames the page). The landing page cannot be renamed. emoji: New emoji shown before the title; an empty string removes it.

Returns: JSON object with the page afterwards.

move_collective_pageA

Move or copy a page, with its subpages, under another page, in this or another collective.

The page lands first among its new siblings. Needs edit rights in both collectives; a page cannot go under itself or its own subpages.

Args: collective_id: The collective the page is in now. page_id: The page to move or copy. parent_id: The page to put it under, in the target collective; 0 or the landing page ID for the top level. to_collective_id: Another collective to move or copy it to (default 0 = stay in this one). copy: True to copy and leave the original where it is. Every call makes another copy.

Returns: JSON with the page afterwards (the copy, when copying).

list_collective_tagsB

List a collective's page tags. Each collective has its own set.

Args: collective_id: The numeric collective ID.

Returns: JSON list of tags with id, name and color. Pages list their tag IDs under "tags".

create_collective_tagB

Create a page tag in a collective.

Args: collective_id: The numeric collective ID. name: The tag's name. color: Six hex digits, with or without "#" (default "0082C9", Nextcloud blue).

Returns: JSON with the new tag (id, name, color).

update_collective_tagA

Rename a collective's page tag or change its color; pages keep it.

Args: collective_id: The numeric collective ID. tag_id: The tag's ID, from list_collective_tags. name: New name. color: New color, six hex digits with or without "#".

Returns: JSON with the tag afterwards.

set_collective_page_tagsA

Set which of the collective's tags a page has; tags left out are taken off.

Args: collective_id: The numeric collective ID. page_id: The numeric page ID. tag_ids: The complete list of tag IDs, from list_collective_tags; [] removes all.

Returns: JSON with the page afterwards, its tag IDs under "tags".

list_collective_page_attachmentsA

List the files attached to a page: those in its attachments folder (images and files embedded in or linked from it) and, for a folder page (one with subpages, a shared page or the landing page), other files next to it. Trashed ones are not listed.

Args: collective_id: The numeric collective ID. page_id: The numeric page ID.

Returns: JSON list of attachments with id, name, mimetype, size, timestamp, type ("text" for the attachments folder, "folder" for files next to the page) and path (usable with get_file).

list_collective_sharesA

List your public links to a collective and to its single pages; other members' links are not shown.

Args: collective_id: The numeric collective ID.

Returns: JSON list of shares with token, page_id (null for a link to the whole collective; a link made from the landing page shows the landing page's ID), editable, has_password, owner and url.

share_collectiveA

Create a public link to a collective, or to one page and its subpages. Anyone with the link can read.

Needs share rights in the collective. Sharing a page without subpages turns it into a folder page (its file becomes /Readme.md, the page ID stays), and sharing the landing page shares the whole collective. Deleting the collective's link leaves page links in place.

Args: collective_id: The numeric collective ID. page_id: A page to share on its own (default 0 = the whole collective). editable: Let people with the link edit too (default false). This needs your edit rights and is ignored when the collective does not let regular members edit; if it fails, the link exists read-only. password: Optional password the link asks for.

Returns: JSON with the share, including its url.

update_collective_shareA

Change whether a public link lets people edit, and its password. Needs edit rights in the collective.

Args: collective_id: The numeric collective ID. token: The share token, from list_collective_shares. editable: Whether people with the link may edit. page_id: The page the link is for, 0 for the whole collective (default: looked up from the token). password: A new password; an empty string removes it; leave out to keep it.

Returns: JSON with the share afterwards.

trash_collectiveA

Move a collective to the trash.

The collective and its pages are soft-deleted. Use restore_collective to undo, or delete_collective to permanently remove it.

Args: collective_id: The numeric collective ID.

Returns: Confirmation message.

restore_collectiveA

Restore a collective from the trash.

Args: collective_id: The numeric collective ID (from list_collectives or prior trash operation).

Returns: JSON object with the restored collective details.

delete_collectiveA

Permanently delete a collective from the trash.

The collective must be in the trash first (use trash_collective). This action is irreversible: all pages are permanently removed.

Args: collective_id: The numeric collective ID. delete_team: Also delete the team (circle) behind the collective, with every membership and anything shared with the team. Needs you to own the team; otherwise nothing is deleted. The team goes even if it existed before the collective. With false (default) it stays as an ordinary team. delete_team_folder: Deleting the team also deletes its team folder (Nextcloud 35+ with the Team folders app, which gives new collectives' teams one) and every file in it. With delete_team, the tool refuses if the team has a team folder unless this is true.

Returns: Confirmation message.

trash_collective_pageA

Move a page to the collective's trash.

The page is soft-deleted. Use restore_collective_page to undo, or delete_collective_page to permanently remove it. The landing page cannot be trashed.

Args: collective_id: The numeric collective ID. page_id: The numeric page ID.

Returns: Confirmation message.

restore_collective_pageB

Restore a page from the collective's trash.

Args: collective_id: The numeric collective ID. page_id: The numeric page ID.

Returns: JSON object with the restored page details.

delete_collective_pageA

Permanently delete a page from the collective's trash.

The page must be in the trash first (use trash_collective_page). This action is irreversible.

Args: collective_id: The numeric collective ID. page_id: The numeric page ID.

Returns: Confirmation message.

delete_collective_tagB

Delete a collective's page tag; pages lose it.

Args: collective_id: The numeric collective ID. tag_id: The tag's ID, from list_collective_tags.

Returns: Confirmation message.

delete_collective_shareA

Remove a public link; it stops working at once.

Args: collective_id: The numeric collective ID. token: The share token, from list_collective_shares. page_id: The page the link is for, 0 for the whole collective (default: looked up from the token).

Returns: Confirmation message.

list_commentsA

List comments on a file.

Returns comments in chronological order (oldest first). Use list_directory to find a file's ID (file_id field).

Args: file_id: The numeric file ID. Get this from list_directory (file_id field). limit: Maximum number of comments to return (1-100, default: 20). offset: Number of comments to skip for pagination (default: 0).

Returns: JSON object with "data" (list of comments) and "pagination" (count, offset, limit, has_more).

add_commentA

Add a comment to a file.

Use @username in the message to mention other users. Maximum message length is 1000 characters.

Args: file_id: The numeric file ID to comment on. message: The comment text (max 1000 characters). Use @username to mention users.

Returns: Confirmation with the new comment ID.

edit_commentA

Edit a comment on a file.

Only the comment author can edit their own comment.

Args: file_id: The numeric file ID. comment_id: The comment ID to edit. message: The new comment text (max 1000 characters).

Returns: Confirmation message.

delete_commentA

Delete a comment from a file.

Only the comment author can delete their own comment. This action is irreversible.

Args: file_id: The numeric file ID. comment_id: The comment ID to delete.

Returns: Confirmation message.

list_addressbooksA

List address books for the current user.

Returns user-owned address books (excludes system-generated books like Accounts and Recently Contacted).

Returns: JSON list of address books with id, name, description, ctag.

get_contactsA

Get contacts from an address book.

Args: book_id: Address book ID (default "contacts"). Use list_addressbooks to find IDs. limit: Maximum number of contacts to return (1-500, default 50). offset: Number of contacts to skip for pagination (default 0).

Returns: JSON with "data" (list of contact objects with uid, full_name, name, emails, phones, addresses, organization, title, note) and "pagination" (count, offset, limit, has_more).

get_contactA

Get a single contact by UID.

Args: uid: The contact UID. Use get_contacts to find UIDs. book_id: Address book ID (default "contacts").

Returns: JSON contact object with uid, full_name, name, emails, phones, addresses, organization, title, note, etag.

create_contactA

Create a new contact in an address book.

Provide at least full_name, or given_name/family_name.

For a single email/phone, use the email/phone params. For multiple, use emails/phones with an array of {"value","type"} objects: emails=[{"value":"a@b.com","type":"WORK"},{"value":"a@home.com","type":"HOME"}] Do not provide both email and emails (or phone and phones).

Args: full_name: Full display name (e.g. "John Doe"). given_name: First name (e.g. "John"). family_name: Last name (e.g. "Doe"). email: Single email address (convenience, adds as TYPE=WORK). phone: Single phone number (convenience, adds as TYPE=CELL). emails: Array of {"value","type"} for multiple emails. Overrides email. phones: Array of {"value","type"} for multiple phones. Overrides phone. organization: Company/organization name. title: Job title. note: Free-text note. book_id: Address book ID (default "contacts").

Returns: JSON contact object with uid, full_name, and all set fields.

update_contactA

Update an existing contact. Only provided fields are changed.

Pass an empty string to clear a scalar field (e.g. note=""). For emails/phones, pass [] to remove all. Do not provide both email and emails (or phone and phones).

Requires the contact's current etag (from get_contacts or get_contact) to prevent conflicting updates.

Args: uid: The contact UID to update. etag: Current ETag for conflict detection. Get from get_contacts/get_contact. full_name: New full display name. given_name: New first name. family_name: New last name. email: Set a single email (replaces all, TYPE=WORK). Pass "" to remove all. phone: Set a single phone (replaces all, TYPE=CELL). Pass "" to remove all. emails: Array of {"value","type"} to replace all emails. Pass [] to clear. phones: Array of {"value","type"} to replace all phones. Pass [] to clear. organization: New organization. Pass "" to remove. title: New job title. Pass "" to remove. note: New note. Pass "" to remove. book_id: Address book ID (default "contacts").

Returns: JSON with the updated contact object.

delete_contactA

Permanently delete a contact from an address book.

Args: uid: The contact UID to delete. book_id: Address book ID (default "contacts").

Returns: Confirmation message.

list_cospend_projectsA

List Cospend (shared expense) projects the current user can access.

Returns: JSON array of full project objects. Each entry includes id (string slug, used as projectId in other tools), name, userid (owner), email, lastchanged, deletiondisabled, archived_ts, currencyname, categorysort/paymentmodesort, and myaccesslevel (1=VIEWER, 2=PARTICIPANT, 3=MAINTAINER, 4=ADMIN). Also embeds members, balance, shares, currencies, categories, paymentmodes for each project, and counters nb_bills / total_spent / nb_trashbin_bills.

get_cospend_projectA

Get full info for a single Cospend project (members, balance, shares, …).

Requires VIEWER access on the project.

Args: project_id: String project id (slug).

Returns: JSON object with the same shape as one entry from list_cospend_projects. Use members for member ids/names and balance for the per-member balance map.

get_cospend_project_statisticsA

Per-member spending statistics for a Cospend project.

Requires VIEWER access. All filters are optional and AND-combined.

Args: project_id: String project id. ts_min: Only include bills with timestamp >= ts_min (Unix seconds). ts_max: Only include bills with timestamp <= ts_max. payment_mode_id: Filter by payment mode. category_id: Filter by category. amount_min: Only include bills with amount >= amount_min. amount_max: Only include bills with amount <= amount_max. currency_id: Convert/filter by currency id. payer_id: Only include bills paid by this member. show_disabled: Include disabled members in the output.

Returns: JSON object with stats (list of {member, balance, paid, spent, filtered_balance}), plus aggregates such as memberMonthlyStats / categoryStats depending on filters.

get_cospend_project_settlementA

Suggested reimbursement transactions to settle a Cospend project.

Requires VIEWER access.

Args: project_id: String project id. centered_on: Member id to center the plan on. All suggested transactions will involve this member (e.g. "everyone pays Alice"). max_timestamp: Settle up to this date (Unix seconds). Member balances will be zero at this date and bills after it are ignored.

Returns: JSON object with transactions (list of {from, to, amount} — from/to are member ids) and balances (map of member-id → current balance).

list_cospend_membersA

List members of a Cospend project.

Requires VIEWER access.

Args: project_id: String project id. last_changed: If provided, only return members modified after this Unix timestamp (used for incremental sync by clients).

Returns: JSON array of members. Each entry has id (integer member id, used as memberId in other tools), name, weight (share weight, default 1), activated (bool — false means soft-disabled but kept for bill history), userid (linked Nextcloud user id, or null for free-form members), color (RGB dict), lastchanged.

list_cospend_billsA

List bills (expenses) in a Cospend project.

Requires VIEWER access.

Args: project_id: String project id. offset: Skip the first N bills (server orders by date desc by default). limit: Max bills to return. Omit for no limit. reverse: If True, oldest-first instead of newest-first. last_changed: Only return bills modified after this Unix timestamp. payer_id: Filter to bills paid by this member. category_id: Filter by category. payment_mode_id: Filter by payment mode. include_bill_id: Force-include this bill id in the result even if it would be paginated out (used to keep a focused bill in view). search_term: Substring match (case-insensitive) on bill what, comment, or amount±1. REQUIRES limit to be set — Cospend silently ignores the search and returns unfiltered results when no limit is provided, so this tool raises ValueError if search_term is given without limit. Pass any limit (e.g. 1000) to apply the filter. deleted: 0 = live bills (default), 1 = trashed bills only.

Returns: JSON object with bills (list of bill dicts — see get_cospend_bill for fields), nb_bills (project-wide bill count under the payer/category/payment-mode/deleted filters; NOT affected by search_term even when search filters bills), allBillIds (full id list before pagination), timestamp (server response time).

get_cospend_billA

Get a single Cospend bill (expense) by id. Requires VIEWER access.

Args: project_id: String project id. bill_id: Integer bill id.

Returns: JSON bill object: id, what (description), amount, payer_id, owers (list of member dicts who share the cost), owerIds (id list), date (YYYY-MM-DD), timestamp (Unix seconds), comment, categoryid, paymentmodeid, repeat ("n"=none, "d"=daily, "w"=weekly, "b"=biweekly, "s"=semi-monthly, "m"=monthly, "y"=yearly), repeatfreq, repeatallactive, repeatuntil, deleted (0=live, 1=in trash), lastchanged.

create_cospend_projectA

Create a new Cospend project. The caller becomes ADMIN of it.

Args: project_id: Desired string id (slug). If the id is already taken, the server appends a digit to make it unique — check the id field of the returned project for the actual id assigned. name: Display name (does not have to be unique).

Returns: JSON of the new project (full info — same shape as get_cospend_project), including the resolved id and the default categories and payment modes that the server seeds.

update_cospend_projectA

Update a Cospend project's settings. Requires ADMIN access.

Pass only the fields you want to change; omit the rest.

Args: project_id: String project id. name: New display name. auto_export: Periodic CSV auto-export frequency. Same code set as bill repeat: "n"=none (default), "d"=daily, "w"=weekly, "b"=biweekly, "s"=semi-monthly, "m"=monthly, "y"=yearly. currency_name: Main currency name (free-form string, e.g. "EUR"). Pass empty string to clear. deletion_disabled: When set, delete_cospend_bill returns HTTP 403 ("project deletion is disabled"). delete_cospend_project is NOT gated by this flag and still succeeds. Useful as a guard against accidental bill removal in shared projects. category_sort: Default category ordering. "a"=alphabetical (default), "m"=manual (custom order field), "u"=most used, "r"=recently used. payment_mode_sort: Same options as category_sort, for payment modes. archived_ts: Archive control with three special values. - 0 → archive now (server records the current Unix timestamp). - -1 → unarchive (clears the field). - any other int → archive at that exact Unix timestamp. Note: 0 ARCHIVES the project (it does not unarchive).

Returns: JSON {"project_id": ..., "updated": true} — the OCS endpoint returns no body, so this is a synthetic confirmation.

create_cospend_memberA

Add a member to a Cospend project. Requires MAINTAINER access.

Args: project_id: String project id. name: Display name of the new member. user_id: Link this member to a Nextcloud user id (optional). If set, the member can see the project in their Cospend UI. weight: Share weight (default 1.0). A weight-2 member counts double in even splits. active: If False, the member is created soft-disabled (rare — usually create active and disable later via update_cospend_member). color: Hex color like "#aabbcc". Omit to let the server pick.

Returns: JSON of the new member: id (use as memberId in other tools), name, weight, activated, userid, color (RGB dict), lastchanged.

update_cospend_memberA

Update a Cospend member. Requires MAINTAINER access.

Pass only the fields you want to change.

IMPORTANT: Setting activated=False on a member who has no bills will permanently delete them, not just disable them. To always keep a recoverable record, ensure the member has at least one associated bill first, or use delete_cospend_member which is unambiguous.

Args: project_id: String project id. member_id: Integer member id (from list_cospend_members). name: New display name. weight: New share weight. activated: True = active, False = disabled (or deleted if no bills). color: New hex color (with or without leading "#"). Pass empty string to clear the color (server picks one on next display). user_id: Link/unlink to a Nextcloud user id. Pass empty string to unlink.

Returns: JSON of the updated member, or null if the member was deleted as described above.

create_cospend_billA

Create a bill (expense) in a Cospend project. Requires PARTICIPANT access.

Args: project_id: String project id. what: Short description of the expense (e.g. "Pizza"). amount: Total amount paid. payer: Member id of the person who paid. payed_for: Non-empty list of member ids who share the cost. Cospend requires at least one ower per bill — passing [] raises ValueError (the server would reject it on create and silently no-op on update, so we reject it up front for both). date: Date string "YYYY-MM-DD". Defaults to today (UTC) if both date and timestamp are omitted; the underlying API requires one. timestamp: Alternative to date — Unix seconds. If both are set, the server uses timestamp. comment: Free-form longer note. category_id: Category id (see project's categories). Omit for uncategorized (id=0). payment_mode_id: Payment mode id (see project's paymentmodes). Omit for unset (id=0). repeat: Repetition mode: "n"=no repeat (default), "d"=daily, "w"=weekly, "b"=biweekly, "s"=semi-monthly, "m"=monthly, "y"=yearly. repeat_freq: Every N units (default 1). E.g. repeat="m", repeat_freq=3 means quarterly. repeat_until: Stop repeating after this date "YYYY-MM-DD". repeat_all_active: 0 (default) = repeat with the same owers, 1 = on each repetition use whoever is currently active.

Returns: JSON {"bill_id": } — the integer id of the new bill.

update_cospend_billA

Update a Cospend bill. Requires PARTICIPANT access.

Pass only fields you want to change. See create_cospend_bill for field semantics.

Args: project_id: String project id. bill_id: Integer bill id. what: New description. amount: New amount. payer: New payer member id. payed_for: New non-empty list of ower member ids (replaces, doesn't merge). Passing [] raises ValueError — the server no-ops silently on empty payedFor, which would look like a successful update but leave owers unchanged. date: New "YYYY-MM-DD" date. timestamp: Alternative to date. comment: New comment. category_id: New category id (0 = uncategorized). payment_mode_id: New payment mode id (0 = unset). repeat: New repeat mode ("n", "d", "w", "b", "s", "m", "y"). repeat_freq: New repeat frequency. repeat_until: New stop date "YYYY-MM-DD". Pass empty string to clear (repeat indefinitely). repeat_all_active: New owers behavior on repeat. deleted: 0 = restore from trash, 1 = move to trash. Use delete_cospend_bill for trashing in normal flow.

Returns: JSON {"bill_id": } confirming the updated bill id.

delete_cospend_projectA

Delete a Cospend project and all its members, bills, and shares.

Requires ADMIN access on the project. The project-delete endpoint does NOT honor deletionDisabled (only delete_cospend_bill is gated by that flag), so this irrevocably removes everything regardless.

Args: project_id: String project id.

Returns: JSON {"project_id": ..., "message": "DELETED"}.

delete_cospend_memberA

Delete (or disable) a Cospend project member. Requires MAINTAINER access.

Members with bills cannot be hard-deleted — they are soft-disabled instead (activated=false) so existing bill history stays valid. Members without any bill are permanently removed.

Args: project_id: String project id. member_id: Integer member id.

Returns: JSON {"project_id": ..., "member_id": ..., "deleted": true}.

delete_cospend_billA

Delete a Cospend bill. Requires PARTICIPANT access.

Returns HTTP 403 ("project deletion is disabled") if the project has deletionDisabled set. Use update_cospend_project to clear that flag first if you need to delete bills.

Args: project_id: String project id. bill_id: Integer bill id. move_to_trash: If True (default), move to the project trash bin — the bill can be restored later by setting deleted=0 via update_cospend_bill. If False, hard-delete (irreversible).

Returns: JSON {"project_id": ..., "bill_id": ..., "moved_to_trash": }.

list_directoryA

List files and folders in a Nextcloud directory.

Args: path: Directory path relative to user's root (default: "/" for root). Example: "Documents", "Photos/Vacation" limit: Maximum number of entries to return (1-500, default 50). offset: Number of entries to skip for pagination (default 0).

Returns: JSON with "data" (list of entries with path, is_directory, size, etc.) and "pagination" (count, offset, limit, has_more).

get_fileA

Read a file's content from Nextcloud.

Text files are returned as text. Image files (PNG, JPEG, GIF, WebP) are returned as viewable images. Other binary files return metadata.

Args: path: File path relative to user's root. Example: "Documents/notes.md"

Returns: File content as text, an image, or metadata for unsupported binary files.

search_filesA

Search for files in Nextcloud by name and/or MIME type.

Searches recursively through all subdirectories of the given path. Results are sorted by last modified date (newest first).

At least one of query or mimetype must be provided.

Args: query: Text to find anywhere in the file name, case-insensitive, taken literally (% and _ are not wildcards). Example: "report" matches "quarterly-report.pdf", "report-2026.docx". path: Directory to search in (default: "/" for entire user folder). Example: "Documents" to only search in Documents. mimetype: Filter by MIME type prefix. Example: "image" for all images, "application/pdf" for PDFs, "text" for all text files. limit: Maximum number of results (1-100, default: 20). offset: Number of results to skip for pagination (default: 0).

Returns: JSON object with "data" (list of matching files) and "pagination" (count, offset, limit, has_more).

upload_fileA

Upload or overwrite a text file in Nextcloud.

Use this for plain-text content (markdown, source code, CSV, JSON, etc.). For binary files (images, PDFs, archives), use upload_file_binary instead.

Creates the file if it doesn't exist. Overwrites if it does.

Args: path: Destination path relative to user's root. Example: "Documents/report.md" content: Text content to write to the file.

Returns: Confirmation message.

upload_file_binaryA

Upload or overwrite a binary file in Nextcloud.

Use this for images, PDFs, archives, or any non-text content. The content must be base64-encoded. For plain-text files, use upload_file instead.

Creates the file if it doesn't exist. Overwrites if it does.

Args: path: Destination path relative to user's root. Example: "Photos/photo.png" content_base64: File bytes encoded as a base64 string. May be empty to create an empty file. content_type: MIME type for the upload request (e.g. "image/png", "application/pdf"). If omitted, inferred from the path extension; falls back to "application/octet-stream". Note: Nextcloud re-derives the stored MIME type from the filename, so this mainly controls the HTTP upload header.

Returns: Confirmation message with the uploaded byte count.

copy_fileA

Copy a file or directory in Nextcloud.

Creates a copy at the destination path. The source remains unchanged. Fails if the destination already exists.

Args: source: Source path. Example: "Documents/report.md" destination: Destination path. Example: "Documents/report-backup.md"

Returns: Confirmation message.

create_directoryB

Create a new directory in Nextcloud.

Args: path: Directory path to create. Example: "Documents/Projects/NewProject"

Returns: Confirmation message.

delete_fileA

Delete a file or directory from Nextcloud.

WARNING: This permanently deletes the file/directory (moves to trash if enabled).

Args: path: Path to delete. Example: "Documents/old-file.txt"

Returns: Confirmation message.

move_fileA

Move or rename a file/directory in Nextcloud.

Args: source: Current path. Example: "Documents/old-name.txt" destination: New path. Example: "Documents/new-name.txt"

Returns: Confirmation message.

list_flowsA

List Nextcloud Flow rules (workflows that act on files automatically).

Args: scope: "user" for the current user's own flows, or "global" for the admin flows that apply to everyone (admin only). limit: Maximum number of flows to return (1-200, default 50). offset: Number of flows to skip for pagination (default 0).

Returns: JSON with "data" (flows with id, name, operation_class, operation_config, entity, events and checks, each check having class, operator and value) and "pagination" (count, offset, limit, has_more).

get_flow_optionsA

List what a Flow rule can be built from in a scope: operations, entities, events and checks.

Read this before create_flow: the available operations depend on the installed apps (Talk's "Write to conversation", for one, or core's "Block file versioning" for global flows), and some only exist in one scope.

Args: scope: "user" or "global" (admin only).

Returns: JSON with "operations" (class, name, description, entity: the entity the operation is bound to or null, events_fixed: true when the operation decides its own events and create_flow takes none, trigger), "entities" (class, name, events with event and name) and "checks" (class, entities it applies to, empty meaning any; for the checks Nextcloud ships also operators and a value description).

create_flowA

Create a Nextcloud Flow rule: when an event happens and all checks match, run an operation.

Use get_flow_options for the operation, entity, event and check class names of the scope; an unknown class name makes Nextcloud fail with a server error. User flows act on the current user's files only. Global flows act on everyone's and need the destructive permission level: a global access control rule whose checks match too much locks every user, this server included, out of their files. Operations that would run a command, or command-line arguments, of the agent's choosing on the server are refused.

Args: operation_class: Class of the operation to run, from get_flow_options. Example: "OCA\Talk\Flow\Operation" checks: Conditions that must all match, at least one. Each is an object with "class", "operator" and "value", e.g. {"class": "OCA\WorkflowEngine\Check\FileName", "operator": "matches", "value": "/.pdf$/i"}. get_flow_options lists operators and value formats for the built-in checks. scope: "user" (default) or "global" (admin only). name: Optional name for the rule. operation_config: The operation's own settings; the format depends on the operation. Talk's "Write to conversation" takes {"m": 1, "t": ""} (m: 1 no mention, 2 mention yourself, 3 mention everyone in the room, moderators only), as an object or a JSON string. Empty for operations without settings. entity: What the rule acts on. Defaults to files ("OCA\WorkflowEngine\Entity\File"), the only entity Nextcloud ships. events: Entity events that trigger the rule, e.g. ["\OCP\Files::postCreate"]. Required unless the operation has events_fixed in get_flow_options, in which case leave it empty.

Returns: JSON with the created flow, as list_flows shows it.

update_flowA

Change a Nextcloud Flow rule. Only the fields you pass change; the operation class cannot.

Global flows need the destructive permission level.

Args: flow_id: The flow's ID, from list_flows. scope: The scope the flow is in: "user" (default) or "global". name: New name. checks: New complete list of checks (replaces the old ones), each with "class", "operator" and "value"; at least one. operation_config: New operation settings, an object or a JSON string (see create_flow). entity: New entity class. events: New complete list of triggering events.

Returns: JSON with the updated flow, as list_flows shows it.

delete_flowA

Delete a Nextcloud Flow rule.

Args: flow_id: The flow's ID, from list_flows. scope: The scope the flow is in: "user" (default) or "global".

Returns: Confirmation message.

list_formsA

List forms visible to the current user.

Args: ownership: Filter. One of: "owned" (forms I created), "shared" (forms shared with me). Omit to get both — the Nextcloud endpoint takes one filter at a time, so this tool calls it twice and merges the results when omitted.

Returns: JSON array of form summaries. Each entry includes id, hash, title, state (0=active, 1=closed, 2=archived), permissions, and metadata. Call get_form(id) for full details including questions.

get_formA

Get a form's full definition including questions, options, and shares.

Args: form_id: Numeric form id from list_forms.

Returns: JSON object with the full form: title, description, access, expires, isAnonymous, submitMultiple, state, maxSubmissions, questions (each with options, type, isRequired, etc.), shares, and submissionCount. Does NOT include submission answers — use list_submissions for those.

list_questionsA

List all questions on a form (same data as get_form.questions).

Args: form_id: Numeric form id.

Returns: JSON array of questions, each with id, type, text, description, isRequired, order, options (for choice questions), and extraSettings.

get_questionA

Get a single question including its options.

Args: form_id: Numeric form id. question_id: Numeric question id.

Returns: JSON object with the question's full definition.

list_submissionsA

List submissions (responses) to a form. Only the form owner can view submissions.

Args: form_id: Numeric form id. query: Optional full-text filter across answer text. limit: Max submissions to return (for pagination). offset: Starting offset (for pagination).

Returns: JSON object with fields: submissions (array of submission objects, each with id, userId, timestamp, answers), questions (the form's questions at submission time), filteredSubmissionsCount.

get_submissionA

Get a single submission by id, including all answers.

Args: form_id: Numeric form id. submission_id: Numeric submission id.

Returns: JSON object with the submission's userId, timestamp, and answers array.

create_formA

Create a new form. Returns the form with a generated id and default empty title.

Args: from_id: Optional id of an existing form to clone (copies questions and options; does not copy submissions or shares).

Returns: JSON of the new form. Use update_form to set title/description, then create_question to add questions.

update_formA

Update a form's properties.

Args: form_id: Numeric form id. key_value_pairs: Object with the fields to change. Common keys: title (str), description (str), isAnonymous (bool), submitMultiple (bool), allowEditSubmissions (bool), expires (unix timestamp, 0 = never), showExpiration (bool), state (0=active, 1=closed, 2=archived), maxSubmissions (int, 0 = unlimited), submissionMessage (str), access (object with permitAllUsers/showToAllUsers), fileFormat, path (destination folder for the generated submissions spreadsheet — must be sent together with fileFormat to (re)link the form to a file).

Returns: JSON of the updated form (refetched after the patch for convenience).

create_questionA

Add a question to a form.

Args: form_id: Numeric form id. question_type: One of: "short" (single-line text), "long" (multi-line text), "multiple" (checkbox), "multiple_unique" (radio), "dropdown", "date", "time", "file", "grid", "color", "linearscale". "datetime" is rejected by Nextcloud — use separate "date" and "time" questions. text: Question text. Defaults to empty; update_question can set it later. subtype: For question_type="grid" only, the cell type: "radio", "checkbox", or "number". from_id: Optional id of an existing question to clone.

Returns: JSON of the new question including its assigned id and order. For choice types (dropdown/multiple/multiple_unique), use create_options to add the answer choices.

update_questionA

Update a question's properties (cannot change order — use reorder_questions).

Args: form_id: Numeric form id. question_id: Numeric question id. key_value_pairs: Object with fields to change. Common keys: text (str), description (str), isRequired (bool), name (str, alternate id for public linking), extraSettings (object; varies by question type).

Returns: JSON of the updated question (refetched after the patch).

reorder_questionsA

Reorder the questions on a form. Must list every question id exactly once.

Args: form_id: Numeric form id. new_order: Array of question ids in the desired order.

Returns: JSON with the updated order for each question id.

create_optionsA

Add one or more answer options to a choice question (dropdown/multiple/etc.).

Args: form_id: Numeric form id. question_id: Numeric question id. Intended for choice-type questions (dropdown, multiple, multiple_unique, linearscale, grid); options on other types are accepted by the server but have no effect. option_texts: Array of option labels to create. Each creates a separate option in order.

Returns: JSON array of created options with their assigned ids and order.

update_optionA

Update an option's properties.

Args: form_id: Numeric form id. question_id: Numeric question id. option_id: Numeric option id. key_value_pairs: Object with fields to change. Common keys: text (str). Do NOT pass order — use reorder_options instead.

Returns: JSON of the updated option (refetched via the parent question).

reorder_optionsA

Reorder the options within a question.

Args: form_id: Numeric form id. question_id: Numeric question id. new_order: Array of option ids in the desired order.

Returns: JSON with the updated order for each option id.

create_form_shareA

Share a form with a user, group, circle, or via public link.

Args: form_id: Numeric form id. share_type: 0=user, 1=group, 3=link (public), 7=circle. share_with: User/group/circle id to share with. Omit for link shares. permissions: Array of strings from: "submit" (fill out), "edit" (modify form definition), "results" (view submissions), "results_delete" (delete submissions), "embed" (render in other pages). Defaults to ["submit"].

Returns: JSON of the new share with its id.

update_form_shareB

Update a share's permissions.

Args: form_id: Numeric form id. share_id: Numeric share id. key_value_pairs: Object with fields to change. Most commonly: permissions (array of strings — see create_form_share).

Returns: JSON of the updated share (refetched via the parent form).

submit_formA

Submit answers to a form on behalf of the current user.

Args: form_id: Numeric form id. answers: Object mapping question id (as string) to array of answer values. Example: {"42": ["my comment"], "43": [1, 3]} where 42 is a text question and 43 has option ids 1 and 3 selected. share_hash: Required if submitting via a public link share instead of direct access. Obtain from the form's hash field.

Returns: Empty OCS data on success (HTTP 201).

update_submissionA

Update an existing submission's answers. Requires allowEditSubmissions on the form.

Args: form_id: Numeric form id. submission_id: Numeric submission id. Must belong to the current user. answers: Full replacement answers object (same shape as submit_form).

Returns: JSON of the updated submission (refetched).

export_submissionsA

Export submissions to a spreadsheet file in the user's Nextcloud storage.

Args: form_id: Numeric form id. path: Destination folder path inside the user's files (no trailing slash). The generated file is created inside this folder. file_format: Optional format override: "csv", "xlsx", "ods". Defaults to the form's configured fileFormat.

Returns: JSON with the created file's name.

delete_formA

Delete a form, including all questions, options, shares, and submissions.

Args: form_id: Numeric form id.

Returns: Confirmation with the deleted id.

delete_questionA

Delete a question and its options from a form.

Args: form_id: Numeric form id. question_id: Numeric question id.

Returns: Confirmation with the deleted id.

delete_optionA

Delete an answer option from a question.

Args: form_id: Numeric form id. question_id: Numeric question id. option_id: Numeric option id.

Returns: Confirmation with the deleted id.

delete_form_shareB

Revoke a share on a form.

Args: form_id: Numeric form id. share_id: Numeric share id.

Returns: Confirmation with the deleted id.

delete_submissionB

Delete a single submission.

Args: form_id: Numeric form id. submission_id: Numeric submission id.

Returns: Confirmation with the deleted id.

delete_all_submissionsA

Delete every submission on a form. Does not delete the form itself.

Args: form_id: Numeric form id.

Returns: Confirmation.

list_groupsA

List Nextcloud groups. Requires admin rights (or delegated user administration).

Nextcloud applies limit and offset to each group backend separately, so with more than one (LDAP and local groups, for example) a page can hold more than limit groups, and paging by offset can repeat or skip some.

Args: search: Optional text to filter groups by ID or display name. limit: Maximum number of groups to take from each group backend (1-200, default 50). offset: Number of groups to skip in each group backend (default 0).

Returns: JSON with "data" (list of groups with id, display_name, user_count, disabled_user_count) and "pagination" (count, offset, limit, has_more). The "id" is what update_user and the other group tools expect.

list_group_membersA

List the users in a group.

Admins, sub-admins of the group and the group's own members may do this.

Args: group_id: The group ID. Use list_groups to find it. limit: Maximum number of user IDs to return (1-500, default 100). offset: Number of user IDs to skip for pagination (default 0).

Returns: JSON with "data" (list of user IDs) and "pagination" (count, offset, limit, has_more). Use get_user for details on a member.

create_groupA

Create a new group. Requires admin rights (or delegated user administration).

Add users to it with update_user (its "groups" field).

Args: group_id: The group ID, used by the other tools to refer to it. Cannot be changed later. display_name: Name shown in the web interface. Defaults to the ID.

Returns: Confirmation message.

delete_groupA

Delete a group. Requires admin rights (or delegated user administration).

The members keep their accounts, but lose the group's memberships and anything shared with the group. The "admin" group cannot be deleted.

Args: group_id: The group ID to delete.

Returns: Confirmation message.

list_mail_accountsA

List all email accounts configured in Nextcloud Mail.

Returns the accounts and their aliases for the current user. Use the account ID to list mailboxes and send emails.

Returns: JSON list of accounts, each with: id, email, aliases.

list_mailboxesA

List mailboxes (folders) for a mail account.

Returns all mailboxes like INBOX, Sent, Drafts, Trash, etc. Use the mailbox ID to list messages in that mailbox.

Args: account_id: The mail account ID. Use list_mail_accounts to find it.

Returns: JSON list of mailboxes, each with: id, name, display_name, unread count, special_role.

list_mail_messagesA

List messages in a mailbox, newest first.

Returns message summaries (subject, sender, date, flags, tags) without the full body. Use get_mail_message with a message ID to read the full content.

Args: mailbox_id: The mailbox database ID. Use list_mailboxes to find it. limit: Maximum number of messages to return (1-100, default 20). cursor: Pagination cursor. Pass the smallest message ID from a previous response to fetch older messages.

Returns: JSON object with "data" (list of message summaries) and "pagination" metadata. Each message has: id, subject, date (unix timestamp), from, to, flags, preview, and tags (display_name and imap_label) when it has any.

get_mail_messageA

Get a full email message including its body.

Retrieves the complete message with body text, message ID, tags, and attachment metadata.

Args: message_id: The message database ID. Use list_mail_messages to find it.

Returns: JSON object with: id, subject, date, from, to, cc, bcc, message_id, body, flags, tags (display_name and imap_label, if any), and attachments list (if any).

send_mailA

Send an email through a Nextcloud Mail account.

The email is sent via the SMTP server configured for the account.

Args: account_id: The mail account ID to send from. Use list_mail_accounts to find it. to: List of recipient email addresses (at least one required). subject: Email subject line. body: Email body text (plain text or HTML depending on is_html). cc: Optional list of CC email addresses. bcc: Optional list of BCC email addresses. is_html: Set to true if the body contains HTML (default: false, plain text).

Returns: Confirmation message on success.

move_mail_messageA

Move a message to another mailbox (folder) of the same mail account.

Mail cannot move messages between accounts; such a move fails with "It is not possible to move across accounts yet".

The moved message gets a new ID, so message_id is no longer valid afterwards and must not be reused. IMAP UIDs are per mailbox, and Nextcloud assigns the new ID when it syncs the destination mailbox. The inbox and mailboxes with background sync enabled are synced automatically; other folders are synced when opened in the Mail app. A message that is already in the destination mailbox is left alone and keeps its ID.

Args: message_id: The message database ID. Use list_mail_messages to find it. destination_mailbox_id: The target mailbox ID, in the message's own account. Use list_mailboxes to find it.

Returns: Confirmation message on success.

set_mail_message_flagsA

Set or clear flags on a message: read/unread, starred, answered.

Only the flags you pass change; the others keep their current value.

Args: message_id: The message database ID. Use list_mail_messages to find it. seen: True marks the message as read, false as unread. flagged: True stars (flags) the message, false removes the star. answered: True marks the message as answered, false clears that mark.

Returns: JSON object with message_id and the flags that were set.

create_mail_tagA

Create a mail tag, or get the existing tag with the same IMAP label.

Tags belong to the current user and are stored on messages as IMAP keywords. Mail derives the IMAP label from the display name (for example "Needs Reply" becomes "$needs_reply"). If a tag with that label already exists, it is returned unchanged, including its color. Mail's built-in tags Important, Work, Personal, To Do and Later have the labels $label1 to $label5; tag messages with those labels rather than creating tags with the same names.

Args: display_name: Tag name shown in the Mail app (at most 128 characters, none of ( ) { ] " \ % * /). color: Hex color such as "#0082c9".

Returns: JSON object with id, display_name, imap_label and color. Pass imap_label to add_mail_message_tag and remove_mail_message_tag.

add_mail_message_tagA

Tag a message. Tagging a message that already has the tag changes nothing.

Args: message_id: The message database ID. Use list_mail_messages to find it. imap_label: The tag's IMAP label (for example "$needs_reply"), as returned by create_mail_tag or shown in the tags of list_mail_messages. Mail's built-in tags use $label1 (Important), $label2 (Work), $label3 (Personal), $label4 (To Do) and $label5 (Later).

Returns: JSON object with message_id and the tag (id, display_name, imap_label, color).

remove_mail_message_tagA

Remove a tag from a message. The tag itself is kept and can still be used on other messages.

Args: message_id: The message database ID. Use list_mail_messages to find it. imap_label: The tag's IMAP label (for example "$needs_reply").

Returns: JSON object with message_id and the removed tag (id, display_name, imap_label, color).

list_notificationsA

List notifications for the current Nextcloud user.

Returns notifications sorted by newest first. Note: the Nextcloud server returns at most 25 notifications and does not support server-side pagination, so the total available is capped by the server regardless of the limit value.

Args: limit: Maximum number of notifications to return (1-25, default 25). offset: Number of notifications to skip for pagination (default 0).

Returns: JSON with "data" (list of notification objects with notification_id, app, user, datetime, subject, message, and optionally link and actions) and "pagination" (count, offset, limit, has_more).

dismiss_notificationA

Dismiss (permanently delete) a single notification by its ID.

Use list_notifications first to find the notification_id to dismiss.

Args: notification_id: The numeric ID of the notification to dismiss.

Returns: Confirmation message.

dismiss_all_notificationsA

Dismiss (permanently delete) ALL notifications for the current user.

This cannot be undone. Use list_notifications first to review what will be dismissed.

Returns: Confirmation message.

get_file_reminderA

Get the reminder set on a specific file.

Returns the due date as an ISO 8601 timestamp, or null if no reminder is set for the file. Also returns null when the file does not exist — the Nextcloud API does not distinguish the two cases, so this tool cannot be used to check file existence.

Args: file_id: Numeric Nextcloud file id. Get this from list_directory, search_files, or any tool that returns file metadata.

Returns: JSON object with file_id and due_date. due_date is null when no reminder is set.

set_file_reminderA

Set or update the reminder on a file.

The due date must be an ISO 8601 timestamp including a timezone and must be in the future. Past timestamps are rejected. Setting a reminder on a file that already has one replaces the existing one.

Args: file_id: Numeric Nextcloud file id. due_date: ISO 8601 timestamp with timezone, e.g. "2026-05-01T10:00:00+00:00" or "2026-05-01T10:00:00Z".

Returns: JSON object with file_id and due_date confirming the value set.

remove_file_reminderA

Remove the reminder set on a file.

Fails with "No reminder is set" if the file has no active reminder.

Args: file_id: Numeric Nextcloud file id.

Returns: Confirmation message.

list_search_providersA

List available Unified Search providers.

Each Nextcloud app can register search providers. Use the provider id with unified_search to search that provider. The filters field shows what extra filters each provider supports beyond the search term.

Common filter types:

  • since/until: ISO 8601 datetime to bound results by date

  • person: user ID to filter by author/participant

  • title-only: boolean, search titles only

Returns: JSON list of providers with: id, name, app, and optionally filters.

unified_searchA

Search a Nextcloud app using the Unified Search API.

Searches a specific provider (e.g. "files", "calendar", "mail", "talk-message", "contacts", "notes"). Use list_search_providers to see all available providers and their supported filters.

Results are cursor-paginated. When has_more is true, pass the returned cursor value to the next call to get more results.

Args: provider: Search provider ID (e.g. "files", "calendar", "mail"). Use list_search_providers to see available providers. term: Search query string. limit: Maximum results to return (1-25, default 25). Server may cap this further based on configuration. cursor: Pagination cursor from a previous search response. Omit for the first page. filters: Optional JSON object of provider-specific filters. Example for files: {"since": "2026-01-01T00:00:00Z", "mime": "text"} Example for talk: {"conversation": "abc123", "person": "admin"} Use list_search_providers to see supported filters per provider.

Returns: JSON object with: provider (name), entries (list of results with title, subline, attributes), has_more (boolean), and cursor (pass to next call for pagination).

list_sharesA

List file/folder shares from Nextcloud.

Without arguments, returns all shares owned by the current user. With a path, returns shares for that specific file or folder. With shared_with_me, returns the shares other users gave the current user instead.

Args: path: Optional file/folder path to filter shares (e.g. "/Documents/report.pdf"). reshares: If true, include shares by other users on the same files. subfiles: If true and path is a folder, list shares of files inside it (not the folder itself). shared_with_me: If true, list the shares the current user received from others (directly, through a group, a team or a Talk conversation, or from another server). "path" is then where the item shows up in the current user's files and uid_owner/displayname_owner say who shared it; federated shares have federated: true and the other server in "remote". Shares still waiting to be accepted are not included (see list_pending_shares). Cannot be combined with reshares or subfiles. limit: Maximum number of shares to return (1-200, default 50). offset: Number of shares to skip for pagination (default 0).

Returns: JSON with "data" (list of share objects) and "pagination" (count, offset, limit, has_more). share_type values: 0=user, 1=group, 3=public link, 4=email, 6=federated, 7=team, 9=federated group, 10=talk room, 12=deck card.

get_shareA

Get details of a specific share by its ID.

Args: share_id: The numeric share ID.

Returns: JSON object with share details: id, share_type, path, permissions, share_with, url (for link shares), expiration, note, label, etc.

list_pending_sharesA

List shares other users offered the current user that are waiting to be accepted.

Shares from users on this server wait here when the user turned off accepting shares automatically (a personal sharing setting) or the admin made accepting them necessary; federated shares from other servers wait here unless they come from a trusted server, whose shares are accepted automatically by default. Accept one with accept_share or decline it with decline_share, passing its id and "federated".

Returns: JSON list of pending shares: id, federated, share_type, path (the item's name), item_type, mimetype (both unknown for federated shares until accepted), uid_owner (the sharer; for federated shares a user on the "remote" server), plus for shares from this server displayname_owner, share_with (a group for group shares), expiration, note, label and declined. Nextcloud keeps offering a group share the user declined, so it stays on this list with declined: true; accept_share still accepts it. A declined federated group share also stays here.

create_shareA

Create a new share for a file or folder.

Args: path: Path to the file or folder to share (e.g. "/Documents/report.pdf"). share_type: Type of share: 0=user, 1=group, 3=public link, 4=email, 6=federated, 10=talk room. share_with: Recipient — required for all types except link (3). User share (0): username. Group share (1): group name. Email share (4): email address. Federated (6): user@remote.server. Talk room (10): room token. permissions: Bitwise permission flags. 1=read, 2=update, 4=create, 8=delete, 16=share. Common values: 1 (read-only), 15 (full, no reshare), 31 (all). Default: all permissions (31) for user/group, read-only (1) for links. Note: file shares automatically strip create (4) and delete (8) flags. password: Optional password for link (3) or email (4) shares. expire_date: Optional expiration date in "YYYY-MM-DD" format. note: Optional note/message for the share recipient. label: Optional display label for link shares (max 255 chars). public_upload: Enable public upload on shared folders (link shares only).

Returns: JSON object with the created share details including id, url (for links), token, etc.

accept_shareA

Accept a share offered to the current user, adding it to their files.

Accepting a share that was already accepted changes nothing. A group share the user declined or left earlier is restored first, since Nextcloud refuses to accept it otherwise.

Args: share_id: The pending share's id from list_pending_shares, as a string (federated share ids can be too long for a JSON number). federated: True for a federated share from another server (federated: true in list_pending_shares). Shares from this server and federated shares are numbered separately.

Returns: Confirmation message.

update_shareA

Update properties of an existing share.

Only provided parameters are changed. Omitted parameters keep their current value.

Args: share_id: The numeric share ID to update. permissions: New permission flags (1=read, 2=update, 4=create, 8=delete, 16=share). password: Set or change password (link/email shares only). Pass "" to remove password. expire_date: Set expiration in "YYYY-MM-DD" format. Pass "" to remove expiration. note: Set or update the share note. Pass "" to clear. label: Set or update the share label. Pass "" to clear. public_upload: Enable (true) or disable (false) public upload on shared folders (link shares only). hide_download: Show (false) or hide (true) the download button on public link shares.

Returns: JSON object with the updated share details.

delete_shareA

Delete (unshare) a share by its ID.

This revokes access for the share recipient. The file/folder itself is not deleted. Called by the recipient on a share they received (list_shares with shared_with_me), it removes the share from their files instead: a share made directly to them is deleted for the owner too, a group share only stops showing up for them. Leaving a federated share tells the other server, except for a federated group share, which goes back to list_pending_shares instead, under the id it had in list_shares.

Args: share_id: The share ID to delete. Use list_shares to find share IDs. Pass federated share IDs as strings: they can be too long for a JSON number. federated: True to leave a federated share received from another server (federated: true in list_shares with shared_with_me). Those are numbered separately from this server's shares.

Returns: Confirmation message.

decline_shareA

Decline a share offered to the current user that is waiting to be accepted.

Declining a share made directly to the user deletes it, so the owner has to share again to offer it again. A declined group share is only hidden from this user: Nextcloud keeps it in list_pending_shares (marked declined) and accept_share can still take it. A declined federated share is removed and the other server is told, except for a federated group share, which Nextcloud keeps offering (under a new id once the user had accepted it before).

Args: share_id: The pending share's id from list_pending_shares, as a string (federated share ids can be too long for a JSON number). federated: True for a federated share from another server (federated: true in list_pending_shares).

Returns: Confirmation message.

list_tagsA

List system tags available in this Nextcloud instance.

System tags are shared labels that can be assigned to files for organization and filtering.

Args: limit: Maximum number of tags to return (1-500, default 50). offset: Number of tags to skip for pagination (default 0).

Returns: JSON with "data" (list of tags with id, name, user_visible, user_assignable) and "pagination" (count, offset, limit, has_more).

get_file_tagsA

Get all system tags assigned to a file.

Use list_directory to find a file's numeric ID (file_id field).

Args: file_id: The numeric file ID.

Returns: JSON list of tags assigned to this file.

create_tagB

Create a new system tag. Requires admin privileges for non-visible/non-assignable tags.

Args: name: Tag display name. user_visible: Whether regular users can see this tag (default: true). user_assignable: Whether regular users can assign this tag to files (default: true).

Returns: JSON with the created tag ID and name.

assign_tagA

Assign a system tag to a file.

Use list_tags to find available tag IDs and list_directory to find file IDs. Assigning an already-assigned tag has no effect.

Args: file_id: The numeric file ID. tag_id: The tag ID to assign.

Returns: Confirmation message.

unassign_tagA

Remove a system tag from a file.

Args: file_id: The numeric file ID. tag_id: The tag ID to remove.

Returns: Confirmation message.

delete_tagA

Permanently delete a system tag.

This removes the tag from all files it was assigned to. This action is irreversible.

Args: tag_id: The tag ID to delete.

Returns: Confirmation message.

list_conversationsA

List Talk conversations the current user is part of.

Returns every conversation the user has joined, sorted by last activity (newest first). Muted and archived conversations are included; Talk has no filter for them.

Args: limit: Maximum number of conversations to return (1-200, default 50). offset: Number of conversations to skip for pagination (default 0). modified_since: Only conversations with activity since this ISO 8601 time with time zone, e.g. to check what changed since the last look. Your own changes to a conversation (read state, favorite, archive, notifications) count as activity, and ones with a call running are always included.

Returns: JSON with "data" (list of conversation objects) and "pagination" (count, offset, limit, has_more).

get_conversationA

Get details about a specific Talk conversation.

Args: token: The conversation token (short alphanumeric ID, e.g. "abc12xyz"). Use list_conversations to find tokens.

Returns: JSON object with conversation details.

get_messagesA

Get chat messages from a Talk conversation.

Returns messages in reverse chronological order (newest first). Uses a compact format: "[id] author: message text" - one line per message. Messages inside a thread are marked after the author: the thread's first message as '[id] author [thread ""]: text', the rest of the thread as "[id] author [thread ]: text".

IMPORTANT: Start with a small limit (20-50). If you need more context, use before_message_id with the oldest message ID from the previous call to paginate backwards through the history.

Args: token: The conversation token. Use list_conversations to find tokens. limit: Maximum number of messages to return (1-200, default: 50). Start small to avoid exceeding response size limits. before_message_id: Fetch messages older than this message ID (for pagination). Use the smallest message ID from a previous call. Default 0 means start from the newest message. include_system: Include system messages like "User joined", "Conversation created" (default: false - only chat messages). thread_id: Only return messages of this thread (default 0 = all messages, including thread messages). Use list_threads to find thread IDs.

Returns: Compact text with one message per line: "[id] author: message". The last line shows pagination info if more messages may exist. Empty when nothing matches, for example when there is nothing older than before_message_id.

get_participantsA

List participants in a Talk conversation.

Args: token: The conversation token. Use list_conversations to find tokens. limit: Maximum number of participants to return (1-200, default 50). offset: Number of participants to skip for pagination (default 0).

Returns: JSON with "data" (list of participant objects with attendee_id, actor_id, display_name, participant_type, in_call) and "pagination" (count, offset, limit, has_more).

get_pollA

Get a poll from a Talk conversation.

Returns poll details including question, options, current votes (if visible), and which options the current user voted for.

Vote visibility depends on the poll's result_mode:

  • "public": votes are visible after you vote.

  • "hidden": votes are only visible after the poll is closed.

Args: token: The conversation token. Use list_conversations to find tokens. poll_id: The poll ID. Poll IDs appear in chat messages when a poll is created.

Returns: JSON object with poll details: id, question, options, status, result_mode, max_votes, votes, num_voters, voted_self.

create_pollA

Create a poll in a Talk conversation.

Polls can only be created in group or public conversations (not one-to-one). A chat message is automatically posted announcing the poll.

Args: token: The conversation token. Use list_conversations to find tokens. question: The poll question (max 32,000 characters). options: List of voting options (minimum 2 options required). Example: ["Yes", "No", "Maybe"] result_mode: 0 for public results (voters see results immediately after voting), 1 for hidden results (results shown only after poll is closed). Default: 0 (public). max_votes: Maximum number of options a user can vote for. 0 means unlimited (user can select all options). Default: 0.

Returns: JSON object with poll details: id, question, options, status, result_mode, max_votes.

vote_pollA

Vote on a poll in a Talk conversation.

Voting replaces any previous vote — calling this again with different option_ids changes your vote. You cannot vote on closed polls.

Args: token: The conversation token. poll_id: The poll ID. Use get_poll to see available polls. option_ids: List of option indices to vote for (0-based). For example, if options are ["Yes", "No", "Maybe"], use [0] to vote "Yes", or [0, 2] to vote "Yes" and "Maybe". The number of choices must not exceed the poll's max_votes (0 means unlimited).

Returns: JSON object with updated poll details including your votes (voted_self) and current vote counts (if visible).

close_pollA

Close a poll in a Talk conversation.

Once closed, no more votes can be cast and results become visible to all participants (regardless of result_mode). Only the poll creator or a conversation moderator can close a poll.

This action is irreversible — a closed poll cannot be reopened.

Args: token: The conversation token. poll_id: The poll ID to close.

Returns: JSON object with the final poll results including all votes and details.

send_messageA

Send a chat message to a Talk conversation.

Supports Markdown formatting. Messages can be up to 32000 characters. Use @mention syntax to mention users: @"user-id" or @"display name".

Threads: pass thread_title to start a new thread with this message as its first message; the thread ID is that message's ID and is returned as thread_id, so pass it as thread_id to keep posting into the thread. An existing message cannot be turned into a thread. thread_title cannot be combined with reply_to or thread_id, and thread_id cannot be combined with reply_to (replying to a message inside a thread posts into that thread anyway).

Args: token: The conversation token. Use list_conversations to find tokens. message: The message text to send (supports Markdown). reply_to: Optional message ID to reply to (default: 0 = not a reply). thread_id: Optional ID of an existing thread to post into without quoting a message (default: 0). Use list_threads to find thread IDs. thread_title: Optional title; when set, the message starts a new thread with this title (default: "" = no new thread). Talk shortens titles longer than 203 characters.

Returns: JSON object of the sent message with its assigned ID, its thread_id (0 when the message is not in a thread) and, for thread messages, thread_title.

create_conversationA

Create a new Talk conversation.

Args: room_type: 1 for a one-to-one conversation, 2 for a group conversation, 3 for a public one. Group conversations are invite-only; public ones can be joined via link. A one-to-one conversation with someone you already have one with returns the existing one. name: Display name for the conversation (ignored for one-to-one). invite: User ID to invite; required for one-to-one, optional for group. description: Optional description for group and public conversations. preset: Optional preset identifier from list_conversation_presets; its settings (permissions, lobby, read-only, ...) are applied to the new conversation. An explicit room_type still wins over the preset's.

Returns: JSON object with the created conversation details, including its token.

delete_messageA

Delete a chat message from a Talk conversation.

Only the message author or a moderator can delete a message. The message is replaced with "Message deleted" in the conversation.

Args: token: The conversation token. message_id: The ID of the message to delete.

Returns: Confirmation message.

leave_conversationA

Leave a Talk conversation.

After leaving, the user will no longer receive notifications or see the conversation in their list. For group conversations, the user can be re-invited. For one-to-one conversations, this removes the conversation permanently for the user.

Args: token: The conversation token of the conversation to leave.

Returns: Confirmation message.

list_threadsA

List the most recently active threads in a Talk conversation.

A thread is started by sending a message with a thread_title (see send_message); its ID is the ID of that first message. Read a thread's messages with get_messages(token, thread_id=...).

Args: token: The conversation token. Use list_conversations to find tokens. limit: Maximum number of threads to return (1-50, default 50). Talk only returns the most recently active threads and has no offset.

Returns: JSON with "data" (list of threads, newest activity first) and "pagination" (count, limit, has_more). Each thread has thread_id, token, title, num_replies, last_activity (Unix timestamp), notification_level (default/always/mention/never) and first/last messages as compact lines "[id] author [thread ]: text" (last is null when there are no replies).

get_threadA

Get details of one thread in a Talk conversation.

Returns the thread's summary, not its messages; use get_messages(token, thread_id=...) to read the messages.

Args: token: The conversation token. Use list_conversations to find tokens. thread_id: The thread ID, which is the ID of the thread's first message. Shown as "[thread ]" in get_messages output.

Returns: JSON object with thread_id, token, title, num_replies, last_activity, notification_level and first/last messages as compact lines.

list_subscribed_threadsA

List the threads the current user follows, across all conversations.

A user follows the threads they start or post in, and the ones whose notification level they set; threads set to "never" are left out. Sorted by last activity (newest first).

Args: limit: Maximum number of threads to return (1-100, default 100). offset: Number of threads to skip for pagination (default 0).

Returns: JSON with "data" (list of threads, same shape as list_threads; use the token field to know the conversation) and "pagination" (count, offset, limit, has_more).

rename_threadA

Rename a thread in a Talk conversation.

Only the author of the thread's first message or a conversation moderator can rename a thread. Talk posts a "thread renamed" system message into the thread.

Args: token: The conversation token. Use list_conversations to find tokens. thread_id: The thread ID (the ID of the thread's first message). title: The new thread title (must not be blank). Talk shortens titles longer than 203 characters.

Returns: JSON object of the updated thread (same shape as get_thread).

set_thread_notification_levelA

Set the current user's notification level for a thread.

Setting any level other than "never" also makes the user follow the thread, so it shows up in list_subscribed_threads; "never" removes it from that list.

Args: token: The conversation token. Use list_conversations to find tokens. thread_id: The thread ID (the ID of the thread's first message). level: One of "default" (use the conversation's setting), "always" (every message), "mention" (only when mentioned) or "never".

Returns: JSON object of the updated thread (same shape as get_thread).

get_message_contextA

Get the messages around one message, e.g. to read the discussion a search result or mention is in.

Reading context leaves the read marker and notifications as they are.

Args: token: The conversation token. message_id: The message to center on. limit: How many messages to fetch before and after it (1-100, default 20). thread_id: Only messages of this thread (default 0 = the whole conversation). include_system: Also show system messages such as joins and edits (default false).

Returns: One line per message, oldest first, in the same "[id] author: text" form as get_messages; the requested message's line is marked with ">>".

get_reactionsA

List who reacted to a message, and with what.

Args: token: The conversation token. message_id: The message ID. reaction: Only this reaction, e.g. "👍" (default: all).

Returns: JSON object mapping each reaction to the display names of who used it.

list_shared_itemsA

List what was shared in a conversation: files, media, polls, locations, pinned messages and more.

Args: token: The conversation token. item_type: One type to list: audio, deckcard, file, location, media, other, pinned, poll, recording or voice. Empty (default) gives the latest few of every type. limit: Maximum items (per type without item_type: 1-20, default 20; with item_type: 1-200).

Returns: JSON object mapping each type to its items, each the chat message that shared it ("[id] author: text"), in Talk's order (newest first; pinned messages by when they were pinned).

search_mentionsA

Find who can be mentioned in a conversation, for writing a message that mentions them.

Args: token: The conversation token. search: Part of a name or ID; an empty string lists the first matches. limit: Maximum results (1-50, default 20). Needs a conversation you can write in.

Returns: JSON list of matches with id, label (display name), source (users, groups, guests, calls for everyone in the room, ...) and "mention", the text to put in the message, e.g. @"john.doe".

edit_messageA

Replace the text of a chat message. Talk marks it as edited and tells the conversation.

Only your own messages (or, for a moderator, any in a group conversation), only within 24 hours, and not system messages or shared polls and locations; for a shared file the new text becomes its caption. Mentions read back from get_messages show names; to keep a mention when editing, write it as search_mentions gives it (@"user-id").

Args: token: The conversation token. message_id: The message to edit. message: The new text. Mentions work as in send_message.

Returns: JSON with the edited message.

add_reactionB

React to a chat message with an emoji. Reacting twice with the same one changes nothing.

Args: token: The conversation token. message_id: The message to react to. reaction: One emoji, e.g. "👍".

Returns: JSON object mapping each reaction on the message to who used it.

mark_conversation_readA

Mark a conversation as read, up to a message or completely.

Marking it completely read also dismisses your Talk notifications for it.

Args: token: The conversation token. message_id: The last message to count as read (default 0 = everything).

Returns: JSON with last_read_message, unread_messages and unread_mention afterwards.

mark_conversation_unreadA

Mark the last message of a conversation as unread again, as the "Mark as unread" menu entry does.

Args: token: The conversation token.

Returns: JSON with last_read_message, unread_messages and unread_mention afterwards.

remove_reactionB

Take back your reaction to a chat message.

Args: token: The conversation token. message_id: The message. reaction: The emoji to remove, e.g. "👍".

Returns: JSON object mapping each remaining reaction to who used it.

set_conversation_preferencesA

Change your own settings for a conversation; other participants are not affected.

Only the settings you pass change, one request each; if one fails, the error names it and the settings already changed before it.

Args: token: The conversation token. favorite: Pin it to the top of your conversation list. archived: Move it to (or out of) your archive; archived conversations stay listed with is_archived true. important: Notify you about it even when your status is Do not disturb. sensitive: Hide message previews for it in the conversation list and notifications. notification_level: When to notify you about messages: "always", "mention" (only when mentioned) or "never". Conversations you never changed report "default", which Talk does not accept as a setting. call_notifications: Whether to notify you when a call starts.

Returns: JSON with the conversation afterwards, as get_conversation shows it.

pin_messageA

Pin a message to the top of the conversation for everyone. Needs moderator rights.

Pinned messages are listed by list_shared_items with item_type "pinned".

Args: token: The conversation token. message_id: The message to pin. until: When the pin should expire, as an ISO 8601 time with time zone (default: until someone unpins it). Talk removes expired pins on its next background job run.

Returns: JSON with the pinned message, or a note that it was already pinned.

set_message_reminderA

Have Talk remind you about a message later with a notification. Replaces an earlier reminder.

Args: token: The conversation token. message_id: The message to be reminded about. remind_at: When, as an ISO 8601 time with time zone, e.g. "2026-10-01T09:00:00+02:00". Must be in the future.

Returns: JSON with token, message_id and remind_at (UTC).

list_message_remindersA

List your upcoming message reminders, soonest first.

Talk returns at most the next 10, including ones already due but not yet sent, and leaves out federated conversations. In conversations you marked sensitive the message text is left empty.

Returns: JSON list of reminders with token, message_id, remind_at (UTC) and the message as a compact line ("[id] author: text").

unpin_messageA

Unpin a message, for everyone (needs moderator rights) or only from your own view.

Args: token: The conversation token. message_id: The pinned message. for_everyone: True (default) removes the pin for all participants; false only hides it for you. Talk remembers one hidden pin per conversation, so hiding another shows this one again.

Returns: Confirmation message.

remove_message_reminderB

Cancel your reminder about a message.

Args: token: The conversation token. message_id: The message the reminder is for.

Returns: Confirmation message.

update_conversationA

Change a conversation for everyone in it. Needs moderator rights.

Only the fields you pass change, one request each; if one fails, the error names it and the fields already changed before it.

Args: token: The conversation token. name: New name, up to 255 characters. description: New description, up to 2000 characters; an empty string removes it. read_only: True to stop everyone from writing (moderators included); also ends a running call. public: True to let anyone with the link join; fails when the instance requires passwords for public conversations, and for one-to-one, note-to-self and breakout conversations. False makes it invite only and removes everyone who joined through the link, so it needs the destructive permission level. preserved: True to protect it: it cannot be deleted, its history not cleared, and its public and joinable settings not changed until it is unpreserved. Owners only; needs Talk 25 (Nextcloud 35).

Returns: JSON with the conversation afterwards.

add_participantA

Add someone to a conversation. Needs moderator rights; adding someone twice changes nothing.

Args: token: The conversation token. participant: Who to add: a user ID, group ID, team (circle) ID, email address or federated cloud ID, matching source. source: "users" (default), "groups" (adds every member), "circles" (a team), "emails" (invites a guest by email) or "federated_users" (someone on another server, when federation is enabled). One-to-one and note-to-self conversations take nobody.

Returns: Confirmation message; get_participants lists attendee IDs.

set_participant_roleA

Make a participant owner, moderator or plain user. Needs moderator rights (owner rights for owners).

Moderators manage the conversation and its participants. Owners are moderators nobody can remove; only owners can make someone owner or demote an owner, and an owner can step down to moderator. Owners need Talk 25 (Nextcloud 35) and exist only in group and public conversations. Guests can only be moderator or user, groups and teams have no role, and the last moderator cannot be demoted.

Args: token: The conversation token. attendee_id: The participant's attendee ID, from get_participants. role: "owner", "moderator" or "user".

Returns: JSON with the participant afterwards.

remove_participantA

Remove someone from a conversation. Needs moderator rights; owners cannot be removed.

Demote an owner to moderator first (set_participant_role). Removing yourself is leaving: it deletes the conversation when you were the only one in it, and is refused when you are its last moderator.

Args: token: The conversation token. attendee_id: The participant's attendee ID, from get_participants.

Returns: Confirmation message.

delete_conversationA

Delete a conversation with all its messages for everyone. Needs moderator rights.

One-to-one conversations cannot be deleted; leave them with leave_conversation.

Args: token: The conversation token.

Returns: Confirmation message.

list_conversation_tagsA

List your conversation tags, the personal groups of your conversation list.

Tags are yours alone; nobody else sees them. The built-in "favorites" and "other" tags cannot be renamed or deleted, and the favorites group is built from set_conversation_preferences(favorite=...), not from tagging.

Returns: JSON list of tags with id, name, type ("favorites", "other" or "custom") and sort_order. get_conversation and list_conversations show each conversation's tag_ids.

list_conversation_presetsA

List the presets create_conversation can start from.

Returns: JSON list of presets with identifier (what create_conversation takes), name, description and the settings create_conversation applies.

create_conversation_tagB

Create a personal conversation tag.

Up to 100 of your own tags, with distinct names of up to 250 characters.

Args: name: The tag's name.

Returns: JSON with the new tag (id, name, type, sort_order).

rename_conversation_tagA

Rename one of your conversation tags; its conversations keep it.

Args: tag_id: The tag's ID, from list_conversation_tags. name: The new name.

Returns: JSON with the tag afterwards.

set_conversation_tagsA

Set which of your tags a conversation has; tags left out are taken off.

Talk silently drops IDs it does not know and keeps at most 20, so compare the returned tag_ids with what you asked for.

Args: token: The conversation token. tag_ids: The complete list of tag IDs, from list_conversation_tags; [] removes all.

Returns: JSON with the conversation afterwards, including tag_ids.

delete_conversation_tagA

Delete one of your conversation tags; its conversations lose it.

Args: tag_id: The tag's ID, from list_conversation_tags.

Returns: Confirmation message.

list_task_listsA

List all task lists (CalDAV calendars with VTODO support) for the current user.

Returns task lists with their properties including name, color, supported component types, and write access status.

Returns: JSON list of task list objects with: id, name, color, components, writable, ctag. Use the id value with other task tools (e.g. "tasks").

get_tasksA

Get tasks from a task list.

Returns all tasks in the list, ordered as stored in CalDAV.

Args: list_id: Task list identifier (default "tasks"). Use list_task_lists to find IDs. limit: Maximum number of tasks to return (1-500, default 50). offset: Number of tasks to skip for pagination (default 0).

Returns: JSON with "data" (list of task objects) and "pagination" (count, offset, limit, has_more). Each task has: uid, summary, description, status, priority, percent_complete, dtstart, due, completed, etag, and optionally categories.

get_taskA

Get full details of a specific task by its UID.

Args: list_id: Task list identifier (e.g. "tasks"). task_uid: The task's UID. Use get_tasks to find UIDs.

Returns: JSON object with full task details: uid, summary, description, status, priority, percent_complete, dtstart, due, completed, etag, and optionally categories.

create_taskA

Create a new task in a task list.

Args: list_id: Task list identifier (e.g. "tasks"). summary: Task title/summary. description: Optional task description/notes. due: Optional due date/time in ISO 8601 format (e.g. "2026-04-10T18:00:00Z"). start: Optional start date/time in ISO 8601 format. status: Task status: "NEEDS-ACTION" (default), "IN-PROCESS", "COMPLETED", or "CANCELLED". priority: Priority 0-9 (0=undefined, 1=highest, 5=medium, 9=lowest). Default 0. percent_complete: Completion percentage 0-100. Default 0. categories: Optional comma-separated category names (e.g. "Work,Urgent").

Returns: JSON object with the created task's uid and summary.

update_taskA

Update an existing task. Only provided fields are changed.

For optimistic locking, pass the etag from a previous get_task or get_tasks call. If the task was modified since that read, the update will fail with a 412 Precondition Failed error. If omitted, the current etag is fetched automatically (still safe against concurrent writes during this call, but won't detect earlier external changes).

Args: list_id: Task list identifier (e.g. "tasks"). task_uid: The task's UID to update. Use get_tasks to find UIDs. summary: New task title. description: New description. Pass "" to clear. due: New due date/time in ISO 8601 format. Pass "" to clear. start: New start date/time in ISO 8601 format. Pass "" to clear. status: New status: "NEEDS-ACTION", "IN-PROCESS", "COMPLETED", or "CANCELLED". priority: New priority 0-9 (0=undefined, 1=highest, 9=lowest). percent_complete: New completion percentage 0-100. categories: New categories as comma-separated string. Pass "" to clear. etag: Optional ETag from a previous read for optimistic locking.

Returns: Confirmation message with the updated task UID.

complete_taskA

Mark a task as completed.

Sets the task's status to COMPLETED, percent-complete to 100, and records the completion timestamp. No-ops if already completed.

For optimistic locking, pass the etag from a previous get_task call.

Args: list_id: Task list identifier (e.g. "tasks"). task_uid: The task's UID to complete. Use get_tasks to find UIDs. etag: Optional ETag from a previous read for optimistic locking.

Returns: Confirmation message.

delete_taskA

Delete a task by its UID.

The task is moved to the calendar trashbin and can be restored from the Nextcloud web interface within the retention period.

Args: list_id: Task list identifier (e.g. "tasks"). task_uid: The task's UID to delete. Use get_tasks to find UIDs.

Returns: Confirmation message.

list_trashA

List items in the Nextcloud trash bin.

Returns files and folders that were deleted and can be restored.

Args: limit: Maximum number of items to return (1-200, default 50). offset: Number of items to skip for pagination (default 0).

Returns: JSON with "data" (list of trashed items with trash_path, original_name, original_location, deletion_time, is_directory, size, file_id) and "pagination" (count, offset, limit, has_more).

restore_trash_itemA

Restore a file or folder from the trash bin to its original location.

The item is restored to its original path. If the original path no longer exists, it is restored to the user's root folder. If a file with the same name already exists, a numeric suffix is added.

Args: trash_path: The trash path identifier from list_trash (e.g. "document.txt.d1711000000").

Returns: Confirmation message.

delete_trash_itemA

Permanently delete a single item from the trash bin.

This action is irreversible. The file or folder will be permanently destroyed and cannot be recovered.

Args: trash_path: The trash path identifier from list_trash (e.g. "document.txt.d1711000000").

Returns: Confirmation message.

empty_trashA

Permanently delete ALL items in the trash bin.

This action is irreversible. All trashed files and folders will be permanently destroyed and cannot be recovered.

Returns: Confirmation message.

get_user_statusA

Get the status of a Nextcloud user.

Returns the user's online status (online, away, dnd, invisible, offline), custom status message, status icon, and when the status will be cleared.

Args: user_id: User ID to look up. Leave empty to get your own status.

Returns: JSON object with user_id, status, message, icon, and clear_at.

set_user_statusA

Set the current user's status.

You can set the online status type, a custom message, or both in a single call. At least one of status_type or message must be provided.

Args: status_type: Online status — "online", "away", "dnd", "invisible", or "offline". Leave empty to keep the current status type. message: Custom status message (e.g., "Working from home", "On vacation"). Leave empty to keep the current message. icon: Status icon emoji (e.g., "🏠", "🌴"). Only used with message. clear_at: Unix timestamp when the status message should be cleared. Use 0 to never auto-clear.

Returns: JSON object with the updated status.

clear_user_statusA

Clear the current user's status message and icon.

This removes the custom status message and icon but does NOT change the online status type (online, away, etc.).

Returns: Confirmation message.

list_versionsA

List versions of a file by its file ID.

Returns the version history. Use the file_id from list_directory or search_files results.

Args: file_id: The numeric Nextcloud file ID. limit: Maximum number of versions to return (1-200, default 50). offset: Number of versions to skip for pagination (default 0).

Returns: JSON with "data" (list of versions with version_id, last_modified, size, content_type, author, label) and "pagination" (count, offset, limit, has_more).

restore_versionA

Restore a file to a previous version.

The file's current content is replaced with the content from the specified version. The pre-restore content is preserved as a new version in the history, so no data is lost.

Args: file_id: The numeric Nextcloud file ID. version_id: The version identifier from list_versions (a unix timestamp string, e.g. "1711000000").

Returns: Confirmation message.

get_current_userA

Get information about the currently authenticated Nextcloud user.

Returns: JSON with user details: id, displayname, email, quota, groups, etc.

list_usersA

List Nextcloud users. Uses server-side pagination.

Args: search: Optional search string to filter users by name/email. limit: Maximum number of users to return (1-200, default 25). offset: Number of users to skip for pagination (default 0).

Returns: JSON with "data" (list of user ID strings) and "pagination" (count, offset, limit, has_more).

get_userB

Get detailed information about a specific Nextcloud user.

Args: user_id: The user ID to look up. Example: "admin", "john.doe"

Returns: JSON with user details: id, displayname, email, quota, groups, language, etc.

create_userA

Create a new Nextcloud user. Requires admin privileges.

Args: user_id: Login name for the new user. password: Password for the new user. display_name: Display name. Defaults to user_id if empty. email: Email address for the new user.

Returns: JSON with the created user ID.

update_userA

Change several fields of a user account in one call. Needs Nextcloud 34 or newer.

Only the fields you pass are changed. Nextcloud validates all of them first and applies none if one fails; the error then names each rejected field. A few requests are skipped without an error, so compare the returned "groups" and "subadmin" with what you asked for: a sub-admin cannot take the user out of groups they do not administer, only full admins can add someone to "admin", and nobody can be made sub-admin of "admin".

Changing another user needs admin rights, or sub-admin rights over one of their groups; sub-admin groups need admin rights. Any user can change their own display name (if the instance allows it), email, language and password. Nextcloud only accepts this call from admins and sub-admins, though, so for a regular user's own account the fields are set one by one instead, and a rejected field then no longer undoes the ones set before it.

After changing your own password, the old one stops working, including for this server if it logs in with it; app passwords keep working.

Args: user_id: The user to change. Example: "john.doe" display_name: New display name. An empty string resets it to the user ID. email: New primary email address. An empty string removes it. password: New password. Must satisfy the instance's password policy. Needs the destructive permission level, since the old password is gone afterwards. quota: Storage quota, e.g. "5 GB", "500 MB", a byte count, "none" (unlimited) or "default". language: Language code, e.g. "en", "de", "fr". manager: User ID of the user's manager (Nextcloud does not check that it exists). An empty string removes it. groups: The complete list of group IDs the user should be in: groups missing from it are left, new ones joined, and [] leaves every group. Get the current ones with get_user and IDs with list_groups. Needs the destructive permission level, since it can remove memberships. Taking your own account out of "admin" this way is refused. subadmin_groups: The complete list of groups the user should administer as a sub-admin; [] removes all. Needs the destructive permission level.

Returns: JSON with the user's details after the change, as get_user returns them.

set_user_enabledA

Enable or disable a user account. Requires admin (or sub-admin) privileges.

A disabled user cannot log in and their sessions and app passwords stop working, but the account, its files and shares are kept. Enable it again to restore access. Nobody can enable or disable their own account. Disabling needs the destructive permission level, enabling the write level.

Args: user_id: The user to enable or disable. enabled: True to enable the account, false to disable it.

Returns: Confirmation message.

delete_userA

Permanently delete a Nextcloud user. Requires admin privileges.

This cannot be undone. The user's data and files will be removed. The user also leaves every team, which deletes the teams they own that have no other member (a pending invitation counts as one), with those teams' team folders and their files (Nextcloud 35+ with the Team folders app). To only block access, disable the account with set_user_enabled instead.

Args: user_id: The user ID to delete.

Returns: Confirmation message.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A3.9/5.0

Scored across 222 tools

Disambiguation4/5

Across 222 tools spanning many Nextcloud apps, most names and descriptions are carefully differentiated (e.g. get_event vs get_events, list_shares vs list_pending_shares vs list_shared_items, create_tag vs create_collective_tag vs create_mail_tag). A few generic names such as create_tag, assign_tag, and list_tags could be confused with app-specific tag tools, and the sheer breadth makes selection harder, but the detailed descriptions largely disambiguate.

Naming Consistency5/5

Nearly all tools follow a snake_case verb_noun pattern: list_*, get_*, create_*, update_*, delete_*, set_*, remove_*, add_*, etc. App-specific prefixes (collective_, cospend_, conversation_, mail_) are applied predictably. No mixed camelCase or wildly inconsistent verb styles appear.

Tool Count1/5

222 tools is an extreme mismatch for an MCP server set, far beyond the 50+ threshold for 'extreme mismatch.' Even if each app area is covered, the total surface is too heavy for an agent to navigate efficiently without specialized routing.

Completeness5/5

The surface provides deep CRUD/lifecycle coverage across files, shares, tags, comments, versions, trash, calendars, tasks, contacts, Talk, forms, collectives, circles, Cospend, mail, announcements, users/groups, flows, activity, and search. Only minor optional operations (e.g. update_announcement, hard delete_mail_message) are absent, which are not dead ends for core workflows.

Maintenance

ActivityMaintained
ResponsivenessUnresponsive