# Tools · Content and engagement

> MCP tools for what happens in the feed: searching, reading, publishing, previewing links, editing, moving and deleting posts, short posts, importing posts from a spreadsheet, commenting and replying, editing and deleting comments, reacting, pinning, the gallery (adding, listing, editing, reacting and deleting), polls (creating, voting, seeing the results, editing, seeing who voted and closing), engagement and your points, and moderation.

The community's day to day: engagement and the moderation queue, finding a post by its title, publishing an announcement with an image, answering the questions from a live session, reacting to introductions, pinning what matters, moving a post to the right space and looking after the gallery's photos. Posts and comments go out under the name of whoever connected the assistant.

Each tool carries a badge: <span class="tool-kind tool-kind-read">Read-only</span> changes nothing, <span class="tool-kind tool-kind-write">Changes</span> creates or changes something right away, and <span class="tool-kind tool-kind-confirm">Asks to confirm</span> only acts after your yes to a summary. See [Money and confirmation](/mcp/dinheiro-e-confirmacao).

## In short

| Tool | What it does | Minimum role | Type |
|---|---|---|---|
| [`list_posts`](#list-posts) | The feed, with comments and reactions | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`search_content`](#search-content) | Finds posts, events, courses, sections, spaces and calls by title | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`list_comments`](#list-comments) | A post's comments | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`create_post`](#create-post) | Publishes a post | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| [`preview_link`](#preview-link) | Shows how a link will look in the post: player or card | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`update_post`](#update-post) | Edits a post's title, text, cover, tags or pin | Author, moderator or finance | <span class="tool-kind tool-kind-write">Changes</span> |
| [`delete_post`](#delete-post) | Deletes a post, with confirmation | Author, moderator or finance | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |
| [`move_post`](#move-post) | Moves a post to another Content or Feed space | Moderator or finance | <span class="tool-kind tool-kind-write">Changes</span> |
| [`create_short_post`](#create-short-post) | Publishes a short post, with no title, in a Feed | Member (not finance) | <span class="tool-kind tool-kind-write">Changes</span> |
| [`list_scheduled_posts`](#list-scheduled-posts) | The scheduled posts: the team sees all, everyone else their own | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`publish_scheduled_post`](#publish-scheduled-post) | Publishes a scheduled post now | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| [`analyze_content_import`](#analyze-content-import) | Reads a spreadsheet of posts and suggests where each column goes | Admin | <span class="tool-kind tool-kind-write">Changes</span> |
| [`preview_content_import`](#preview-content-import) | The post import summary and the first 10 rows, saving nothing | Admin | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`start_content_import`](#start-content-import) | Imports the spreadsheet's posts, with their original date and silently | Admin | <span class="tool-kind tool-kind-write">Changes</span> |
| [`get_content_import`](#get-content-import) | Progress and report of a post import | Admin | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`create_comment`](#create-comment) | Comments or replies | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| [`update_comment`](#update-comment) | Edits a comment's text | Author, moderator or finance | <span class="tool-kind tool-kind-write">Changes</span> |
| [`delete_comment`](#delete-comment) | Deletes a comment, with confirmation | Author, moderator or finance | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |
| [`remove_comment_video`](#remove-comment-video) | Removes a comment's Drop; the comment keeps its text | Author, moderator or finance | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |
| [`set_video_poster`](#set-video-poster) | Chooses the cover of a hosted video (Drop, post video or recording) from an image | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| [`set_video_cover_frame`](#set-video-cover-frame) | Picks a hosted video's cover from the video's own frames | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| [`remove_video_poster`](#remove-video-poster) | Removes the chosen cover; the automatic one comes back | Any | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |
| [`create_drop_description`](#create-drop-description) | Writes the text of a post, short post or comment from what the person said in the Drop | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| [`get_drop_description`](#get-drop-description) | The state and text of a `create_drop_description` request | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`add_reaction`](#add-reaction) | Reacts with an emoji | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| [`pin_post`](#pin-post) | Pins or unpins in the feed | Moderator or finance | <span class="tool-kind tool-kind-write">Changes</span> |
| [`add_gallery_image`](#add-gallery-image) | Adds an image to a Gallery space | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| [`add_gallery_images`](#add-gallery-images) | Adds up to 20 images, by link or file, to a Gallery space | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| [`list_gallery_images`](#list-gallery-images) | A gallery's images, with author and reactions | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`update_gallery_image`](#update-gallery-image) | Changes an image's title or description | Author, moderator or finance | <span class="tool-kind tool-kind-write">Changes</span> |
| [`react_to_gallery_image`](#react-to-gallery-image) | Reacts to a gallery image | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| [`delete_gallery_image`](#delete-gallery-image) | Deletes a gallery image | Author, moderator or finance | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |
| [`get_leaderboard`](#get-leaderboard) | The top of the leaderboard | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`get_my_points`](#get-my-points) | Your points and your position on the leaderboard | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`get_member_points`](#get-member-points) | A member's points balance and statement | Admin | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`get_points_settings`](#get-points-settings) | Points as currency: on, name, start and circulation | Admin | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`update_points_settings`](#update-points-settings) | Turns points on as currency and names it | Admin | <span class="tool-kind tool-kind-write">Changes</span> |
| [`get_ranking_rules`](#get-ranking-rules) | Whether engagement is on, and the points per action | Admin | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`update_ranking_rules`](#update-ranking-rules) | Turns it on or off and changes the points | Admin | <span class="tool-kind tool-kind-write">Changes</span> |
| [`get_ranking_levels`](#get-ranking-levels) | The levels, with the minimum points and the week's activity | Admin | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`update_ranking_levels`](#update-ranking-levels) | Saves the levels and requirements | Admin | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |
| [`get_level_progress`](#get-level-progress) | What is left this week to stay at or move up a level | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`list_moderation_queue`](#list-moderation-queue) | What is waiting for approval | Moderator or finance | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`moderate_item`](#moderate-item) | Approves or rejects an item in the queue | Moderator or finance | <span class="tool-kind tool-kind-write">Changes</span> |
| [`react_to_comment`](#react-to-comment) | Reacts to a comment with an emoji | Member (not finance) | <span class="tool-kind tool-kind-write">Changes</span> |
| [`get_feed_stats`](#get-feed-stats) | The home page numbers, and yours | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`get_feed_highlights`](#get-feed-highlights) | The Feed's side column: upcoming events, trending posts, new members and leaderboard | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`get_space_highlights`](#get-space-highlights) | A Content space's side column: its tags and what's trending | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`get_ranking_dashboard`](#get-ranking-dashboard) | The engagement page: leaderboard, levels and rules | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`list_my_points_history`](#list-my-points-history) | Your points history, action by action | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`recalculate_member_points`](#recalculate-member-points) | Recalculates a member's points | Admin | <span class="tool-kind tool-kind-write">Changes</span> |
| [`adjust_member_points`](#adjust-member-points) | Adds or takes away someone's points, with the reason | Admin | <span class="tool-kind tool-kind-write">Changes</span> |
| [`list_badges`](#list-badges) | The badge catalog, with how many people hold each one | Admin | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`get_badge`](#get-badge) | A badge, with who holds it | Admin | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`create_badge`](#create-badge) | Creates a badge, with an image | Admin | <span class="tool-kind tool-kind-write">Changes</span> |
| [`update_badge`](#update-badge) | Changes the name, description, image or who sees it | Admin | <span class="tool-kind tool-kind-write">Changes</span> |
| [`delete_badge`](#delete-badge) | Removes a badge from the catalog | Admin | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |
| [`award_badge`](#award-badge) | Gives a badge to up to 100 people | Admin | <span class="tool-kind tool-kind-write">Changes</span> |
| [`revoke_badge`](#revoke-badge) | Takes a badge back from someone, without notice | Admin | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |
| [`list_member_badges`](#list-member-badges) | A member's badges | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`remove_post_video`](#remove-post-video) | Removes a post's video (hosted file or link) or a short post's Drop | Author, moderator or finance | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |
| [`get_media_url`](#get-media-url) | 1-hour link to a hosted video or image | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| [`reprocess_media`](#reprocess-media) | Restarts a hosted video's conversion when it failed | Moderator or finance | <span class="tool-kind tool-kind-write">Changes</span> |

## `list_posts`

<span class="tool-kind tool-kind-read">Read-only</span>

**List feed posts.** The feed (posts, statuses, events and courses), newest first, with comment and reaction counts. *Minimum role: any.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `space_id` | id | No | Only one space (from `list_spaces`). On a Feed, it follows the Feed's `feed_scope`: `space` lists only the space's own items, `section` (and any other module) lists the whole section |
| `section_id` | id | No | A section (from `list_spaces`): every space in it, whatever the `feed_scope`. Wins over `space_id` |
| `type` | `all`, `status`, `content`, `events`, `courses` | No | Only one kind of item |
| `tag` | text | No | Only the posts and statuses with this [tag](/espacos/feed#clickable-tags) (e.g. `jobs`), within the same space or section, like clicking the tag in the app. Case, accents and `#` don't matter: `Jobs` = `jobs` = `#jóbs` |
| `page`, `limit` | number | No | Pagination |
| `sort` | `recent`, `activity` | No | `recent` (the default) or `activity`: pinned first, then by latest activity (publication, comment or reply); each item carries `last_activity_at` |

**Returns:** the items, each with the **id** and the **type** that `create_comment`, `add_reaction` and `pin_post` need, the author, the title or text, the counts, whether it's pinned and its `tags`. Each item also brings `embeds`: the links in the text as a player or a card (see [`preview_link`](#preview-link)). For the team, each post carries `canCreateCampaign`: whether it can become a campaign with [`create_campaign_from_content`](/mcp/ferramentas-comunidade#e-mail-campaigns).

**Ask like this:** *"Which posts got the most comments this week?"* · *"What was posted in the Announcements space?"* · *"List the posts tagged #jobs in the Community space."*

## `search_content`

<span class="tool-kind tool-kind-read">Read-only</span>

**Search by title.** Searches the titles of posts, events, courses, sections, spaces and calls for papers, ignoring case and accents, in a single search across the whole community. *Minimum role: any; each person finds what they can see.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `query` | text, 2 to 200 | Yes | Part of the title. For short posts, it searches the text |
| `types` | list: `posts`, `events`, `courses`, `spaces`, `calls` | No | Default: all. `spaces` includes sections |
| `limit` | number, up to 50 | No | Default 20 |

**Returns:** the matches, each with its type, id, title and, when there is one, the space, the section, the module, the date and the status.

**Notes:** people outside the team only find what is published and approved; spaces and sections closed to the person are left out. A space the person can open shows up even inside a section closed to them. It's the same search as [`GET /api/search`](/api/referencia/feed/get-search).

**Ask like this:** *"Find the post How the community works."*

## `list_comments`

<span class="tool-kind tool-kind-read">Read-only</span>

**List a post's comments.** The comments on a content post or a status. *Minimum role: any.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `type` | `content`, `status` | Yes | The item type, from `list_posts` |
| `post_id` | id | Yes | The item id, from `list_posts` |

**Returns:** the comments, with the id (which `create_comment` uses in `reply_to`), the author, the text and the date.

**Ask like this:** *"Which comments on the welcome post haven't been answered yet?"*

Accepts the types `course` (course discussion) and `course_lesson` (lesson discussion, with the `course` argument naming the course). Enrolled students and the team read, finance included.

## `create_post`

<span class="tool-kind tool-kind-write">Changes</span>

**Publish post.** Publishes a text post in a Feed or Content space. *Minimum role: any role that can post in that space.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `space_id` | id | Yes | From `list_spaces` |
| `title` | text | Yes | |
| `text` | Markdown | Yes | The body of the post, in [Markdown](/mcp/ferramentas#markdown-text): bold, italic, lists, links, subheadings, quote and code |
| `image_url` | link | No | The post's cover: a public (`http`/`https`) link to a JPEG, PNG, WebP or GIF image of up to 50 MB. See [Images](/mcp/ferramentas#images) |
| `published_at` | ISO 8601 date and time | No | The [publication date](/espacos/conteudo#publication-date) of a post that went out earlier (e.g. `2024-03-15T10:00:00Z`): past or now, never the future. Owner and admin only |
| `author` | profile id, e-mail, name or link | No | Posts [on behalf of another member](/espacos/conteudo#posting-on-behalf-of-another-member), only for someone with a role below yours. Owner and admin only |
| `tags` | list, up to 10 of 40 characters | No | The post's [clickable tags](/espacos/conteudo#clickable-tags). A leading `#` and duplicates are dropped; above the limit, nothing is published and the assistant gets the reason |
| `comments_disabled` | yes or no | No | `true` turns off the post's comments (nobody comments, the team included; existing ones stay), `false` turns them on. The author, owner, admin or moderator |

**Returns:** the created post, with its id (for `pin_post`), the cover, the `tags` and the `embeds`. The text comes back in Markdown, with `text_format: "markdown"`.

**Links become a player or a card.** The links in the text become a [player or a card](/espacos/conteudo#links-become-a-player-or-a-card) by themselves, up to 5 per post: there is no need to call [`preview_link`](#preview-link) first. A link that hadn't been read yet shows up in `embeds` a few seconds after publishing.

**Ask like this:** *"Post a welcome in the Feed for everyone who joined this week, mentioning each of them by name."*

**Video.** `video_url` (a YouTube or Vimeo link) or a video **hosted on Memberfy**, through `video_file_url` (a link; MP4, WebM or MOV up to **2 GB**) or `video_file_base64` (about **7 MB**), with `video_file_type` and `video_file_name`. Send one video only, not both; the post goes out as a video post. The file is private: only whoever opens the post sees it. See [Hosted video](/espacos/conteudo#hosted-video).

**Date and author.** With `published_at` more than 5 minutes in the past, the post goes in silently: no engagement points, out of the news e-mails and highlights, no new badge. With `author`, the post shows as the person's and **always** goes in silently, whatever the date; the [Logs](/membros/registros-de-atividades) record who posted it. The owner posts on behalf of admins, moderators, finance and members; the admin, on behalf of moderators, finance and members. Otherwise nothing is published and the assistant gets the reason. *"Bring over these 40 posts from our old blog, each with its original date and author."*

**Notes:** without `author`, the post goes out with the name and photo of whoever connected. The space's **Who can post** rule applies: in a staff-only space, a member is refused. The post goes out immediately; scheduling isn't possible yet. If the image can't be used, nothing is published and the assistant gets the reason.

`publish_at` (a date and time after now, up to 1 year ahead) schedules the post: it only goes out at that time, and the answer carries `schedule`. See [`list_scheduled_posts`](#list-scheduled-posts).

## `preview_link`

<span class="tool-kind tool-kind-read">Read-only</span>

**Preview a link.** Shows how a link will look inside a post, before publishing: the same preview the app editor shows on paste. A player for YouTube (live streams and a start time set with `t=` included), Spotify, Vimeo, Loom, SoundCloud, Google Maps, Instagram posts and reels and LinkedIn posts; a card (title, description, site, image) for other pages; an app card for the app stores; the image itself for a GIF or an image link. Shorteners are followed. It asks for no confirmation and saves nothing. *Minimum role: any.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `url` | `http` or `https` link, up to 2,048 | Yes | The link to preview |

**Returns:** `provider`, `type`, `title`, `description`, `site_name`, `thumbnail_url` (or `snapshot_thumbnail_url`, the page snapshot, taken after the post is saved), `becomes_player`, the `player` size and `shows_as`, a sentence on how the link shows up, in your language.

**Notes:** an invalid link, or one to a private or internal address, is refused with the reason (a post with it still publishes, with the link as text). There's a limit of a few dozen previews per minute; past it, the assistant says how many seconds to wait. See [Links become a player or a card](/espacos/conteudo#links-become-a-player-or-a-card).

**Ask like this:** *"How will this YouTube video look in the post?"* · *"Does this Spotify link become a player?"*

## `update_post`

<span class="tool-kind tool-kind-write">Changes</span>

**Edit a post.** Changes a post's title, text or cover, and pins or unpins it. Only what is sent changes. *Minimum role: the author, or moderator, finance and up.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `post` | id or link | Yes | |
| `type` | `content`, `status` | No | Default: `content`. On a status (short post), the text, the date and the Drop change |
| `title` | plain text | No | |
| `text` | Markdown | No | In a short post (`status`), only bold, italic, links and line breaks |
| `image_url` or `image_base64` | link or file | No | The new cover. See [Images](/mcp/ferramentas#images) |
| `remove_image` | yes or no | No | Removes the cover |
| `pinned` | yes or no | No | Pins or unpins (moderator, finance and up) |
| `published_at` | ISO 8601 date and time | No | Changes the [publication date](/espacos/conteudo#publication-date), also of a short post: past or now. Owner and admin only |
| `tags` | list, up to 10 of 40 characters | No | The tags, of a post or a short post. **Replaces** the whole list; `[]` (or empty) removes them all; without the parameter, the tags stay as they are |
| `comments_disabled` | yes or no | No | `true` turns off the post's comments (nobody comments, the team included; existing ones stay), `false` turns them on. The author, owner, admin or moderator |

**Ask like this:** *"In the post How the community works, swap the cover for this image and pin it to the top."* · *"Add the tags jobs and remote to the latest post in the Jobs space."*

Changing the text redoes the `embeds`.

**Notes:** the post doesn't move to another space.

`update_post` also accepts `video_url`, `video_file_url` and `video_file_base64` (the new video **replaces** the previous one, and the old file is deleted). `remove_video` only clears a link; for a hosted video, use [`remove_post_video`](#remove-post-video).

On a short post (`type: status`), `video_file_url` or `video_file_base64` (MP4, WebM or MOV, up to **350 MB**) replaces the [Drop](/espacos/drops) and deletes the previous one; `video_url` is refused. To take the Drop off, `remove_post_video` with `type: status`.

On a post with comments off, `create_comment` is refused: *"Comments are turned off on this post."*

`publish_at` reschedules a post that is waiting or failed (on a status, `publish_at` alone is enough).

## `remove_post_video`

<span class="tool-kind tool-kind-confirm">Asks to confirm</span>

**Remove a post's video.** Deletes the hosted video file for good (the storage comes back) or clears the link, and the post becomes a text post. On the first call it shows the post; on the second, with the `confirmation_token`, it removes. *Role: the author, or moderator, finance and up.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `post` | id or link | Yes | |
| `type` | `content`, `status` | No | Default: `content`. With `status`, removes a short post's [Drop](/espacos/drops); refused when the short post has no text, since it would be left empty (use `delete_post` for that). |

## `reprocess_media`

<span class="tool-kind tool-kind-write">Changes</span>

**Convert a video again.** Restarts the conversion of a hosted video (a post's `videoMediaId` or an event's `recordingMediaId`) when it failed. It answers `409` when the video didn't fail or the community doesn't have adaptive streaming, and it's limited to 20 per hour. *Minimum role: moderator (or finance).*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `media_id` | id | Yes | The media id of the video whose conversion failed |

## `get_media_url`

<span class="tool-kind tool-kind-read">Read-only</span>

**A hosted media link.** A signed link that works for **1 hour**, to watch or open: a post's video (`videoMediaId`), an event's recording (`recordingMediaId`), a gallery or classified image (`mediaId`). Only those who can open the space and the item get it: a post in review, an expired ad or a paid event aren't open to everyone. Don't store or pass on the link; ask for another when it expires. The response says when it expires: `url_expires_at` (date and time) and `url_valid_seconds` (seconds left). *Role: any.* Also the [Drop](/espacos/drops) of a short post or comment (`videoMediaId`).

| Parameter | Type | Required | Description |
|---|---|---|---|
| `media_id` | id | Yes | The media id on the post, event, image or ad |

## `delete_post`

<span class="tool-kind tool-kind-confirm">Asks to confirm</span>

**Delete a post.** Asks for confirmation: the first call shows the post, and only the second deletes it. *Minimum role: the author, or moderator, finance and up.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `post` | id or link | Yes | |
| `type` | `content`, `status` | No | Default: `content` |

## `move_post`

<span class="tool-kind tool-kind-write">Changes</span>

**Move post to another space.** Takes a post to another Content or Feed space in the community; its place in the feed goes with it. *Minimum role: moderator or finance.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `post` | id or link | Yes | |
| `to_space` | id, link, address or name | Yes | A Content or Feed space |

**Ask like this:** *"This job post ended up in Announcements; move it to the Jobs space."*

**Notes:** a space of another module (Courses, Events…) is refused.

## `create_short_post`

<span class="tool-kind tool-kind-write">Changes</span>

**Publish short post.** A short post, up to 500 characters and with no title, in a Feed space, like the app's quick field. For a post with a title and a cover, the assistant uses `create_post`. *Role: owner, admin, moderator or a member who can post in the space.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `space` | id, link, address or name | Yes | A Feed space |
| `text` | text, up to 500 | Yes, without a video | Takes only bold, italic, links and line breaks, in [Markdown](/mcp/ferramentas#markdown-text) . With a video, it can be left out |
| `visibility` | `public`, `members`, `private` | No | |
| `published_at` | ISO 8601 date and time | No | A past publication date, as in [`create_post`](#create-post). Owner and admin only |
| `author` | profile id, e-mail, name or link | No | Posts on behalf of another member with a role below yours, always silently, as in [`create_post`](#create-post). Owner and admin only |
| `tags` | list, up to 10 of 40 characters | No | The short post's [clickable tags](/espacos/feed#clickable-tags), as in [`create_post`](#create-post) |
| `video_file_url` or `video_file_base64` | link or file | No | The short post's [Drop](/espacos/drops): a ready-made video (MP4, WebM or MOV, up to **350 MB**), with `video_file_type` and `video_file_name`. The assistant doesn't record: it sends a file or link. |
| `comments_disabled` | yes or no | No | `true` turns off the post's comments (nobody comments, the team included; existing ones stay), `false` turns them on. The author, owner, admin or moderator |

**Returns:** the short post, with the `embeds` of the links in the text, as in [`create_post`](#create-post). With a video, also `videoMediaId` and `video.processing_status` (`queued`, `processing`, `ready`, `failed`, or empty when the community doesn't convert); the link comes from [`get_media_url`](#get-media-url). The video is private like the post and is prepared for streaming up to 720p in the background.

**Ask like this:** *"Write in the Feed: 'Live today at 8 p.m., link in the event!'"*

`publish_at` schedules the short post, as in [`create_post`](#create-post).

## Scheduled posts

A post with `publish_at` in [`create_post`](#create-post) or [`create_short_post`](#create-short-post) waits for its time in the **Scheduled** list (see [Content](/espacos/conteudo)). Neither tool asks to confirm.

## `list_scheduled_posts`

<span class="tool-kind tool-kind-read">Read-only</span>

**Scheduled.** The posts waiting to go out, soonest first: type (`content` or `status`), title, excerpt, space, author, `publish_at`, status (`scheduled`, or `failed` when the author can no longer post in the space) and `can_manage`. The team (owner, admin, moderator and finance) sees everyone's; anyone else only their own. *Minimum role: any.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `space_id` | id | No | Only one space's |
| `page` | number | No |  |
| `limit` | number, up to 50 | No |  |

**Ask like this:** *"What is scheduled to go out this week?"*

**Notes:** rescheduling is [`update_post`](#update-post) with `publish_at`; publishing now, [`publish_scheduled_post`](#publish-scheduled-post); canceling, [`delete_post`](#delete-post).

## `publish_scheduled_post`

<span class="tool-kind tool-kind-write">Changes</span>

**Publish now.** The date becomes now and the post goes out once, with the feed, the points and the e-mail notice; a failed one is tried again. The author, whoever scheduled it, the owner, the admin, the moderator and finance may do it; for anyone else, or a post that is not waiting, the answer is *not found*. If the author can no longer post in the space, it is refused and the post stays failed. *Minimum role: any.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `post` | id or link | Yes | The scheduled post (from `list_scheduled_posts`) |
| `type` | `content` or `status` | No | Default: `content` |

**Ask like this:** *"Publish the scheduled post about the live session now."*

## `analyze_content_import`

<span class="tool-kind tool-kind-write">Changes</span>

**Analyze the spreadsheet of posts.** The first step of [importing content from a spreadsheet](/espacos/importar-conteudo), for example when bringing the community over from another platform. Sends the file (.xlsx or .csv, up to 5 MB, 5,000 rows and 100 columns) and returns the analysis. Nothing is imported; an analysis that isn't confirmed expires in 24 hours. *Minimum role: admin.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `file_url` | link | One of the two | Public link to the .xlsx or .csv |
| `csv_text` | text | One of the two | The CSV's content |
| `file_name` | text | No | The name kept in the history |

**Returns:** the sheets, the header row, the total of rows and each column with 3 examples and the suggested destination.

## `preview_content_import`

<span class="tool-kind tool-kind-read">Read-only</span>

**Preview the post import.** Reads the file again (another sheet, header row, delimiter or encoding) and, with the mapping and the options, returns the summary and the first 10 rows as they will look, saving nothing. *Minimum role: admin.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `import_id` | id | Yes | From the analysis |
| `sheet`, `header_row`, `delimiter`, `encoding` | | No | How to read the file |
| `mapping` | list | No | Where each column goes: `column` (0 = column A) and `target`: `title`, `body`, `author_email`, `published_at`, `space`, `type`, `tags` or `ignore` |
| `space_id` | id | Without a space column | The default space, a Content or Feed one (from `list_spaces`) |
| `type` | `post`, `article`, `short` | No | The type of the rows without a type column. Default: `post`; `short` only in a Feed space, up to 500 characters |
| `visibility` | `public`, `members` | No | Default: `members` |
| `date_order` | `DMY`, `MDY` | No | For dates like 03/04/2024 |
| `unknown_author` | `skip`, `importer` | No | An author e-mail that belongs to no one in the community: skips the row (default) or publishes under the name of whoever imports, with a warning |

**Returns:** how many will be imported, by type, with their original date, skipped by reason and with warnings by code, the images to download, the date order and time zone used, and the first 10 rows (type, title, space, author, date, tags and warnings). The reasons and warnings are explained in [Why a row was skipped](/espacos/importar-conteudo#why-a-row-was-skipped).

## `start_content_import`

<span class="tool-kind tool-kind-write">Changes</span>

**Import the posts.** The same parameters as the preview, with `mapping` required. Puts the import in the queue; each row becomes a post with its original date, silently: no one is notified, no e-mail goes out to members and no one earns points. That's why it doesn't ask for a `confirmation_token`, but the assistant shows the `preview_content_import` summary and waits for your yes first. *Minimum role: admin.*

**Notes:** the author is the community member with the `author_email`, only with a role below that of whoever imports; otherwise the row is skipped. A post with the same title and date as an existing one is skipped, so repeating the spreadsheet doesn't duplicate anything. Images in the text are hosted on Memberfy (up to 20 per row and 300, or 500 MB, per import; the rest stay as links). One post import per community at a time. Whoever imports gets an e-mail at the end.

**Ask like this:** *"Import this spreadsheet of posts from our old blog into the Articles space, with the original dates and authors."*

## `get_content_import`

<span class="tool-kind tool-kind-read">Read-only</span>

**Follow the post import.** The status (`ANALYZED`, `QUEUED`, `IMPORTING`, `COMPLETED`, `FAILED`, `CANCELLED`, `ABANDONED`), the rows processed, imported, skipped, failed and with warnings, and the skipped rows (with the reason), the ones that failed and the ones that went in with a warning (like `IMAGE_FAILED`, with the image's link), with the id of what was created. *Minimum role: admin.*

## `create_comment`

<span class="tool-kind tool-kind-write">Changes</span>

**Comment or reply.** Comments on a feed item, or replies to a comment. *Minimum role: any.* Commenting requires access to the item's space (`403` without it).

| Parameter | Type | Required | Description |
|---|---|---|---|
| `type` | `content`, `status`, `event`, `course` | Yes | The item type, from `list_posts` |
| `item_id` | id | Yes | The item id |
| `text` | plain text, up to 2,000 | Yes, without a video | No formatting: Markdown marks are stripped . On a short post (`status`), up to 280. With a video, it can be left out |
| `reply_to` | id | No | The id of the comment to reply to (from `list_comments`). On `content`, `status`, `course` and `course_lesson` items |
| `video_file_url` or `video_file_base64` | link or file | No | The comment's [Drop](/espacos/drops), only on `content` and `status` items: a ready-made video (MP4, WebM or MOV, up to **350 MB**). |

**Returns:** the new comment. With a video, also `videoMediaId` and `video.processing_status`.

**Ask like this:** *"Reply to every unanswered question on yesterday's live post, thanking them and saying we'll cover it next time."*

Accepts `course` and `course_lesson`, with `reply_to` to reply (one level). Enrolled students and the team write, finance included; a draft or archived course is refused (`409`).

## `update_comment`

<span class="tool-kind tool-kind-write">Changes</span>

**Edit a comment.** Changes a comment's text. *Minimum role: the author, or moderator, finance and up.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `type` | `content`, `status` | Yes | |
| `post` | id or link | Yes | The comment's post |
| `comment_id` | id | Yes | From `list_comments` |
| `text` | text, up to 2,000 | Yes, without a video |  |
| `video_file_url` or `video_file_base64` | link or file | No | Replaces the comment's [Drop](/espacos/drops) (MP4, WebM or MOV, up to **350 MB**) and deletes the previous one. Only the author sends a new video. |

Also edits course and lesson comments (the author only). Courses have no Drop. To take the Drop off, [`remove_comment_video`](#remove-comment-video).

## `delete_comment`

<span class="tool-kind tool-kind-confirm">Asks to confirm</span>

**Delete a comment.** With confirmation. *Minimum role: the author, or moderator, finance and up.* Same parameters, without `text`.

Also deletes course and lesson comments, and still asks for confirmation. The author and the team (owner, admin, moderator and finance) delete.

## `remove_comment_video`

<span class="tool-kind tool-kind-confirm">Asks to confirm</span>

**Remove a comment's video.** Deletes for good the [Drop](/espacos/drops) of a comment on a post or short post; the comment keeps its text. Refused when the comment has no text, since it would be left empty (use `delete_comment` for that). On the first call it shows the comment; on the second, with the `confirmation_token`, it removes. *Role: the author, or moderator, finance and up.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `type` | `content`, `status` | Yes | |
| `post` | id or link | Yes | The comment's post |
| `comment_id` | id | Yes | From `list_comments` |

**Ask like this:** *"Take the video off my comment on the welcome post, but keep the text."*

## `add_reaction`

<span class="tool-kind tool-kind-write">Changes</span>

**React.** Reacts to a feed item. *Minimum role: any.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `type` | `content`, `status`, `event`, `course` | Yes | |
| `item_id` | id | Yes | |
| `reaction` | 👍 ❤️ 🔥 🙌 😊 👏 🎉 | Without `remove` | One of the seven reactions |
| `remove` | yes or no | No | `true` takes your reaction back |

**Returns:** the recorded reaction.

**Ask like this:** *"React with 🎉 to the introductions from people who joined today."* · *"Take my reaction off the welcome post."*

One reaction per person per item: reacting again with another emoji changes it.

Accepts `course` and `course_lesson` as the target, with the same seven reactions.

## `pin_post`

<span class="tool-kind tool-kind-write">Changes</span>

**Pin to the feed.** Pins an item to the top of the feed, or unpins it. *Minimum role: moderator or finance.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `type` | `content`, `status`, `event`, `course` | Yes | |
| `item_id` | id | Yes | |
| `pinned` | yes or no | No | Default: pin. With `false`, unpins |

**Returns:** the item with its new state.

**Ask like this:** *"Pin the community rules post."*

## `add_gallery_image`

<span class="tool-kind tool-kind-write">Changes</span>

**Add an image to a gallery.** Downloads an image from a link and puts it in a Gallery space. *Minimum role: any role that can post in that space.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `space_id` | id | Yes | A Gallery space (`list_spaces` with `module: gallery`) |
| `image_url` | link | Yes | A public (`http`/`https`) link to a JPEG, PNG, WebP or GIF image of up to 50 MB. See [Images](/mcp/ferramentas#images) |
| `title` | text, up to 200 | No | The image's title in the gallery |

**Returns:** the image in the gallery, with its address and thumbnail.

The image is stored in a **private area** (1-hour link, see [`get_media_url`](#get-media-url)), and can come by link (up to 50 MB) or by file (`image_base64`, up to 5 MB; `image_type` optional).

**Ask like this:** *"Put this photo from the meetup in the Meetups gallery: https://…/photo.jpg"*

## `add_gallery_images`

<span class="tool-kind tool-kind-write">Changes</span>

**Add several images to a gallery.** Puts up to 20 images in a Gallery space in a single call, each by link or file, with the same delivery as [`add_gallery_image`](#add-gallery-image). *Minimum role: any role that can post in that space; the space's rule of who can post and its approval apply to every image.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `space_id` | id | Yes | A Gallery space (`list_spaces` with `module: gallery`) |
| `images` | list, 1 to 20 | Yes | Each image with `image_url` (a link up to 50 MB) or `image_base64` (`image_type` optional), plus its own optional `title` and `description` |
| `title` | text, up to 200 | No | The title for images without their own |
| `description` | text, up to 2,000 | No | The description for images without their own |
| `tags` | list, up to 30 | No | Tags for every image |

**Returns:** how many were added (`added`) and how many failed (`failed`) and, in `results`, each image in the order sent: `added`, with `image_id` and `moderation_status`, or `failed`, with the reason.

Each base64 file goes up to 5 MB, and all of them together must fit in the call's 10 MB, so large images go by link. One bad image doesn't stop the others; ask again with only the ones that failed. If the gallery refuses the person asking (role, rule of who can post, space), the rest isn't sent. Nothing is deleted, so there's no confirmation; there's no bulk delete: `delete_gallery_image` deletes one at a time.

**Ask like this:** *"Upload these photos to the Meetup 2026 gallery with the title APICON Rio: https://…/1.jpg, https://…/2.jpg, https://…/3.jpg"*

## `list_gallery_images`

<span class="tool-kind tool-kind-read">Read-only</span>

**List gallery images.** The images of a Gallery space, newest first, with title, author and reactions. *Minimum role: any role that can see the space.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `space` | id, link, address or name | Yes | The Gallery space |
| `page`, `limit` | number | No | `limit` up to 50 |

**Returns:** the images, with the id the other gallery tools ask for and, on each one:

| Field | What it is |
|---|---|
| `image_url` | The full-size image, which the assistant can open to look at |
| `thumbnail_url` | The thumbnail, lighter, good for comparing photos |
| `url_expires_at` | When both links stop working (about 1 hour later) |
| `url_valid_seconds` | How many seconds are left before they expire |
| `size_bytes`, `mime_type`, `processing_status` | Size, format and whether the image is ready |

An image still processing comes with empty links and a note: just list again in a few seconds. Once the links expire, the assistant lists again or calls [`get_media_url`](#get-media-url) with the `mediaId`. The links shouldn't be stored or passed on.

**Ask like this:** *"Are there duplicate photos in the Meetup 2026 gallery? Show me and delete the copies."* The assistant compares the thumbnails and deletes the copies with `delete_gallery_image`, which asks for confirmation. See the recipe [Find the duplicate photos in the gallery](/mcp/receitas#67-find-the-duplicate-photos-in-the-gallery).

## `update_gallery_image`

<span class="tool-kind tool-kind-write">Changes</span>

**Edit gallery image.** Changes an image's title or description (and **replaces the file** with a new image, by link or file; the id, the title and the tags stay, and the old file is deleted). *Role: whoever added the image, or moderator, finance and up.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `image_id` | id | Yes | From `list_gallery_images` |
| `title` | text, up to 255 | No | |
| `description` | text | No | |

## `react_to_gallery_image`

<span class="tool-kind tool-kind-write">Changes</span>

**React to gallery image.** With 👍 ❤️ 🔥 👏 😊 🙌 or 🎉. Reacting again changes it; `remove: true` takes it back. *Minimum role: any.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `image_id` | id | Yes | From `list_gallery_images` |
| `reaction` | one of the seven emojis | Without `remove` | |
| `remove` | yes or no | No | `true` takes your reaction back |

## `delete_gallery_image`

<span class="tool-kind tool-kind-confirm">Asks to confirm</span>

**Delete gallery image.** *Role: whoever added the image, or moderator, finance and up.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `image_id` | id | Yes | From `list_gallery_images` |

**Returns:** on the first call, the image's title and author, and the confirmation code.

## `get_leaderboard`

<span class="tool-kind tool-kind-read">Read-only</span>

**View engagement.** The top of the community's points engagement. *Minimum role: any.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `period` | `all`, `30d`, `7d` | No | Default: `all` |
| `section_id` | id | No | Only the points earned in this section |
| `limit` | number, up to 100 | No | How many in the leaderboard (default 10) |
| `course` | id, slug or link | No | That course's leaderboard instead of the community's |

**Returns:** each row with the position, points, level and badges. People with the same points share the position (`rank` 1, 2, 2, 2, 5, with `isTied`), and the assistant says *"tied for 2nd"* instead of inventing an order; `level` (the number of the person's level in the community's ladder) with the name the community gave it in `level_name` (the default ones go from Newcomer to Legend), `levelId` and `levelImageUrl`; `badges` (the 8 most recent you may see; someone else's private badges never show) and `badgeCount` (the total, for the *"+N"*); and `previousRank`, the position in the previous period of the same length with `7d` and `30d` (`null` when the person didn't score in it: they are *new*, not *down*). Your own position in the period, even outside the top, comes from [`get_ranking_dashboard`](#get-ranking-dashboard).

**Ask like this:** *"Who are the top 10 in engagement?"*

With `course`, returns that course's leaderboard (the top 10 by completed lessons and your position), if the course shows one.

## `get_my_points`

<span class="tool-kind tool-kind-read">Read-only</span>

**My engagement points.** Your points and your position in the community's engagement. *Minimum role: any.*

Parameters: none.

**Ask like this:** *"How many points do I have, and where do I stand?"*

With [points as currency](/monetizacao/pontos-na-loja) on, it also returns `balance`: the balance and the statement (`limit`, `before`).

## Points as currency

[Points in the Store](/monetizacao/pontos-na-loja): the balance spent on products priced in points. Spending never lowers points, rank or level. Your own balance is in [`get_my_points`](#get-my-points); redeeming a product is [`redeem_product_with_points`](/mcp/ferramentas-vendas#redeem-product-with-points).

## `get_member_points`

<span class="tool-kind tool-kind-read">Read-only</span>

**A member's points balance.** A member's balance and statement: whether the balance is on and redeeming works (`usable`), the currency name, the balance (it can be negative; negative buys nothing), points and level (spending lowers neither) and the entries, newest first: gain, spend (with the purchase and the product), refund, opening and an adjustment the team made on itself (it counts in points, never in the balance). *Minimum role: admin.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `member` | id or e-mail | Yes |  |
| `limit` | number, up to 100 | No | Entries (default 50) |
| `before` | date | No | The previous page's `next_before` |

**Ask like this:** *"What is Ana's points balance, and what did she spend it on?"*

**Notes:** your own balance is in [`get_my_points`](#get-my-points).

## `get_points_settings`

<span class="tool-kind tool-kind-read">Read-only</span>

**Points as currency.** Whether gamification and the balance are on, whether redeeming works, the currency name (empty = *points*), when and how the balance started (`current`: today's points became balance; `zero`: everyone started at 0), how much circulates (the sum of the positive balances) and, before the first start, a preview of what would circulate with each option. *Minimum role: admin.*

Parameters: none.

**Ask like this:** *"How many points are circulating in the community?"*

## `update_points_settings`

<span class="tool-kind tool-kind-write">Changes</span>

**Turn points on as currency.** Turns the balance on or off (off by default, on every plan) and names the currency. The **first** time it is turned on, `start` chooses for good: turning it off and on again never reopens the choice, so that first start asks to confirm, with the preview; everything else runs at once. Off, nobody redeems and balances stay. *Minimum role: admin.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `enabled` | true/false | No |  |
| `start` | `current` or `zero` | No | First time only: `current` (default) turns today's points into balance; `zero` starts everyone at 0 |
| `currency_name` | text, up to 30 characters | No | Like "coins"; empty or `null` goes back to *points* |

**Ask like this:** *"Turn on points as currency, called coins, starting from zero."*

**Notes:** a product's points price is set in [`create_product`](/mcp/ferramentas-vendas#create-product) and [`update_product`](/mcp/ferramentas-vendas#update-product).

## `get_ranking_rules`

<span class="tool-kind tool-kind-read">Read-only</span>

**View engagement rules.** Whether engagement is on and how many points each action is worth. *Minimum role: admin.*

Parameters: none.

**Ask like this:** *"How many points is a comment worth?"*

## `update_ranking_rules`

<span class="tool-kind tool-kind-write">Changes</span>

**Change engagement rules.** Turns engagement on or off and changes the points per action. *Minimum role: admin.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `enabled` | yes or no | No | |
| `points` | action → points | No | The actions come from `get_ranking_rules`, e.g. `{"comment": 10}` |
| `daily_caps` | action → number | No | The daily points cap per action (1 to 10,000; `null` removes it), e.g. `{"comment": 20}`. Over it, the action happens with no points and does not count for badge rules |

**Ask like this:** *"Commenting is now worth 10 points."*

See [Engagement](/espacos/ranking).

## `get_ranking_levels`

<span class="tool-kind tool-kind-read">Read-only</span>

**See the levels.** The community's [levels](/membros/gamificacao#levels), from the first to the last. *Minimum role: admin.*

Parameters: none.

**Returns:** each level with `level` (the number), `id`, `name` (`defaultName` while it is the translated default name), `minPoints`, `maxPoints`, `imageUrl` and the `requirements`, the week's activity, each with `actionType`, `minCount`, `spaceId`, `space_name` and `actionActive` (`false`: the action is off in the points rules and is not counting). Also the limits (2 to 20 levels, names up to 40 characters, up to 5 requirements, 1 to 1,000 per week), the actions that count as a requirement, the time zone and the rule text, in the person's language. A community that never touched the levels has the 9 default ones, with no requirements.

**Ask like this:** *"What are the community's levels and what does each one ask for?"*

## `update_ranking_levels`

<span class="tool-kind tool-kind-confirm">Asks to confirm</span>

**Save the levels.** Writes the whole ladder: send **every** level, in order. A level with `id` is kept (what it leaves out stays as it is), one without `id` is created, and a stored level left out of the list is **removed** (not possible if an access rule uses it). Beforehand, the summary shows the levels, the ones leaving and how many people move up and down; the level changes without firing any workflow or webhook. *Minimum role: admin.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `levels` | list, 2 to 20 | Yes | Each level: `id` (an existing level), `name` (up to 40 characters, no repeats), `min_points` (the first is 0, each one higher than the one before), `image_url` (`null` removes the image) and `requirements` |
| `levels[].requirements` | list, up to 5 | No | Each one: `action` (a gamification action, except the team's adjustment), `min_count` (1 to 1,000 times a week, Monday to Sunday in the community's time zone) and, optionally, `space` (id, link or exact name, only for actions that happen in a space). The first level has no requirements; `[]` removes them all |

**Ask like this:** *"The Kernel level now asks for 3 posts a week, on top of the 500 points."*

**Notes:** a removed level that still opens a space or a section in **Who gets in** makes the save be refused, saving nothing, with `code: level_in_use` and the names; take the level off there with `update_space_access` or `update_section` and `min_level: null` and save again.

## `get_level_progress`

<span class="tool-kind tool-kind-read">Read-only</span>

**Weekly level progress.** The same the profile shows: the points, the current level and the next one, and each requirement with `thisWeek`, `lastWeek`, `minCount`, `missing_this_week` and `done_this_week`. The week under way is the one that decides, on Monday, whether the person stays at the level; to move up, what counts is the points still missing (`points_missing`) and the next level's requirements this week. *Minimum role: any.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `member` | id, e-mail or link | No | Without it (or with `me`), your own. Only the team (owner, admin, moderator and finance) sees someone else's; everyone else gets 403 |

A requirement tied to a space you cannot access comes without the space's name, with `space_label` *"a space you cannot access"*; the team sees the name.

**Ask like this:** *"What do I still need this week to keep my level?"*

## `list_moderation_queue`

<span class="tool-kind tool-kind-read">Read-only</span>

**Moderation queue.** What is waiting for approval, or the moderation numbers. *Minimum role: moderator or finance.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `type` | `summary`, `posts`, `courses`, `events`, `gallery`, `status` | No | Default: `posts`. `summary` returns the numbers |

**Ask like this:** *"Is anything waiting for approval?"*

## `moderate_item`

<span class="tool-kind tool-kind-write">Changes</span>

**Approve or reject.** Approves or rejects an item in the moderation queue. *Minimum role: moderator or finance.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `type` | `posts`, `courses`, `events`, `gallery`, `status` | Yes | |
| `item_id` | id | Yes | From `list_moderation_queue` |
| `decision` | `approve`, `reject` | Yes | Approve or reject |
| `reason` | text | No | Required to reject |

**Ask like this:** *"Approve the posts in the queue that have no external link."*

See [Moderation](/membros/moderacao).

## `react_to_comment`

<span class="tool-kind tool-kind-write">Changes</span>

**React to a comment.** Reacts to a comment with 👍 ❤️ 🔥 🙌 😊 👏 or 🎉. *Minimum role: anyone but finance.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `type` | `content`, `status` | Yes | `content` for posts and articles, `status` for short posts |
| `post` | id or link | Yes | The comment's post |
| `comment_id` | id | Yes | From `list_comments` |
| `reaction` | one of the 7 emojis | Without `remove` |  |
| `remove` | yes or no | No | `true` takes your reaction back |

**Returns:** the recorded reaction.

**Ask like this:** *"React with 👏 to Ana's comment on the welcome post."*

**Notes:** reacting again changes the reaction; to take it back, `remove: true`.

Also reacts to course and lesson comments.

## `get_feed_stats`

<span class="tool-kind tool-kind-read">Read-only</span>

**Community numbers.** The numbers the home page shows. *Minimum role: any.*

Parameters: none.

**Returns:** the community's members, posts, events and courses, who was active today, and your own level, points, position, posts, comments and events attended.

**Ask like this:** *"How many members do we have, and who was on today?"*

## `get_feed_highlights`

<span class="tool-kind tool-kind-read">Read-only</span>

**Feed highlights.** What the [Feed's side column](/espacos/feed#side-column) shows, only with what you can open. *Minimum role: any.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `space_id` | id | No | A Feed space: the widgets turned on in that Feed. Without it, the default ones |

**Returns:** the widgets that have items: `events` (up to 5 upcoming events, with `starts_at_local` and `ends_at_local` in the event's own time zone, and `isLive`), `trending` (up to 5 trending posts from the last 7 days), `newMembers` (up to 6) and `leaderboard` (top 5 of the last 30 days, with gamification on), when on in the Feed. Suggests `rsvp_event` (the first event), `list_comments` (the first trending post), `get_member` (the first new member), `get_ranking_dashboard` and, for the team, `update_space`.

**Ask like this:** *"What's trending in the community?"* · *"What are the upcoming events?"*

## `get_space_highlights`

<span class="tool-kind tool-kind-read">Read-only</span>

**Tags and what's trending in a space**. What the [Content space's side column](/espacos/conteudo#the-side-column) shows, only with the posts you can read. *Minimum role: any, as long as you can open the space.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `space_id` | id | Yes | A Content space (from `list_spaces`) |

**Returns:** the blocks that have items: `tags` (up to 50, most used first, with `tag`, `key` and `count`, and the `total` of distinct tags) and `trending` (up to 5 posts: first the ones from the last 30 days by reactions and comments from other people, then the ones with the most reactions of all time and the most recent, with `reactions`, `comments` and the author; only missing when the space has no post you can read). `{}` when the module has no side column. A space from another community is not found; a space you can't open is refused with the reason. The suggested next step is `list_posts` with the space and the most used tag.

**Ask like this:** *"What are the tags and what's trending in the Podcasts space?"*

## `get_ranking_dashboard`

<span class="tool-kind tool-kind-read">Read-only</span>

**Engagement page.** The whole **Engagement** page. *Minimum role: any.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `period` | `all`, `30d`, `7d` | No | Default: `all` |
| `section_id` | id | No | Only the points earned in this section |
| `limit` | number, up to 100 | No | How many in the leaderboard (default 50) |

**Returns:** the period's leaderboard, your position and progress to the next level, the community totals, how members spread over the levels, and the points each action is worth. It also brings the leaderboard with shared positions, level, badges and `previousRank`, as in [`get_leaderboard`](#get-leaderboard), and, in `currentUser`, `periodRank` and `periodPoints` (your position and points in the period, even outside the returned rows).

**Ask like this:** *"Who scored the most in the last 30 days?"*

## `list_my_points_history`

<span class="tool-kind tool-kind-read">Read-only</span>

**My points history.** Your own points history in this community, newest first. *Minimum role: any.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `limit` | number, up to 100 | No | Default 20 |

**Returns:** each action (post, comment, event, login…), the points it earned and when.

**Ask like this:** *"Why do my points look like this?"*

## `recalculate_member_points`

<span class="tool-kind tool-kind-write">Changes</span>

**Recalculate points.** Recalculates a member's engagement points from their recorded actions, when the total looks wrong. *Minimum role: admin.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `member` | id, e-mail or link | Yes |  |
| `section_id` | id | No | Only the points of this section |

**Returns:** the profile and the recalculated score.

**Ask like this:** *"Ana's points look wrong. Recalculate them."*

**Notes:** afterwards, `member_activity` shows what the person did.

## `adjust_member_points`

<span class="tool-kind tool-kind-write">Changes</span>

**Adjust someone's points.** Adds (positive points) or takes away (negative) engagement points of someone in the community, with the reason in the person's points log. The ranking and the profile change at once, and a recalculation keeps the adjustment. It is the same action as the workflows' **Adjust points** step. Runs without confirmation. *Minimum role: admin.*

| Parameter | Type | Required | Description |
|---|---|---|---|
| `member` | id, e-mail or link | Yes |  |
| `points` | integer, from -100,000 to 100,000, not zero | Yes | Negative takes away |
| `reason` | text, up to 200 characters | Yes | Shown in the person's points log |

**Returns:** the adjusted points and the new total; with engagement off, nothing changes (`skipped`).

**Ask like this:** *"Give Ana 50 points for yesterday's talk."*

## Badges

The seals of the [badge catalog](/membros/engajamento#badges). A badge is named by its id or exact name; a person, by id, e-mail or an app link. Whoever gets a badge is notified in the bell and by e-mail (**Achievements** category); taking it back sends no notice. Nobody holds the same badge twice. The ready-made recipe **Give a badge** (`award_badges`) does the whole path, with the dry run first.

## `list_badges`

<span class="tool-kind tool-kind-read">Read-only</span>

**List badges.** The catalog, with image, description, public or private and how many people hold each one. *Minimum role: admin.*

## `get_badge`

<span class="tool-kind tool-kind-read">Read-only</span>

**See a badge.** The badge and who holds it, newest first (`holders_limit`). *Minimum role: admin.*

## `create_badge`

<span class="tool-kind tool-kind-write">Changes</span>

**Create a badge.** `name` (up to 60, unique in the community), `description` (up to 300, optional), `visibility` (`public` by default, or `private`: only the holder, the owner and the admins see it) and the image, required, by `image_url` or `image_base64` (stored as a PNG of up to 512 × 512 px). Nobody gets it yet: give it with `award_badge`, or let a course (`completion_badge` on `update_course`), an event (`check_in_badge` on `update_event`) or a workflow (the `badge.award` action) give it. *Minimum role: admin.* `rule`: awards on its own: `trigger` (an action from `get_ranking_rules` or a moment: `course.completed`, `event.checked_in`, `quiz.passed`, `form.submitted`, `survey.answered`, `proposal.accepted`, `recognition.received`, `upvote.topic_done`, `attendance.checked_in`), `min_count` (1 to 1,000), `space` (optional), `window` (`always`, `last7`, `last30`, `month`) and `min_member_days` (optional). The past does not count. See [Award automatically](/membros/engajamento#award-automatically).

**Ask like this:** *"Create the Handshake badge, public, with this image, for those who finish the welcome course."*

## `update_badge`

<span class="tool-kind tool-kind-write">Changes</span>

**Edit a badge.** Changes `name`, `description` (`null` clears it), `visibility` and the image; it applies at once for those who already hold it. *Minimum role: admin.* Also `rule`, as in `create_badge`: an object replaces the rule, `null` removes it, absent keeps it.

## `delete_badge`

<span class="tool-kind tool-kind-confirm">Asks to confirm</span>

**Remove a badge.** The summary says how many people hold it; after your yes, it leaves the profiles and the ranking, the course or event that gave it stops giving it, and the grants stay in the history. *Minimum role: admin.* When the badge opens spaces or sections in **Who gets in**, the summary warns how many stop opening: whoever got in only through it loses access at once.

## `award_badge`

<span class="tool-kind tool-kind-write">Changes</span>

**Give a badge.** `badge` (id or name), `members` (1 to 100), `reason` (optional; only the team sees it) and `dry_run` (only shows who would get the badge and the **Achievements** e-mail, and who already holds it). It doesn't ask for confirmation, like the other e-mail sends: show the dry run to the person first. Returns how many got it, who already held it and who wasn't found. *Minimum role: admin.*

**Ask like this:** *"Give the Speaker badge to Ana and Bruno. Show me first who gets the e-mail."*

## `revoke_badge`

<span class="tool-kind tool-kind-confirm">Asks to confirm</span>

**Take a badge back.** Takes the badge from one person (`badge`, `member`): it leaves the profile and the ranking, the grant stays in the history and the person isn't notified. Someone who doesn't hold it comes back with `changed: false`. *Minimum role: admin.*

## `list_member_badges`

<span class="tool-kind tool-kind-read">Read-only</span>

**A member's badges.** Someone's badges (`member`, or `"me"`), with the origin and the date. Private ones only show for the person, the owner and the admins; the reason, only for the owner and the admins. *Minimum role: any.*

**Ask like this:** *"Which badges does Ana have?"*

## `set_video_poster`

Chooses the **cover** of a hosted video (`media_id`: the `videoMediaId` of a post, short post or comment, or an event's `recordingMediaId`) from an image by link or file (JPEG, PNG or WebP; not GIF). It replaces the cover chosen before (that image is deleted). Works before or after the video is in a post. Only whoever uploaded the video and, once it is in a post or comment, only if they are its author (the team for an event recording); anyone else gets 403. Returns the signed video, with `thumbnailUrl`, `posterUrl` and `posterMediaId`. See [Drops › The cover](/espacos/drops#the-cover).

## `remove_video_poster`

Removes the cover chosen for a hosted video: the image is deleted for good and the automatic cover (a frame of the video) comes back; the video stays. **Asks to confirm**: the first call shows the video; the second, with `confirmation_token`, removes the cover. Who: whoever uploaded the video (and its author once it is in a post).

## `set_video_cover_frame`

Picks the cover of a hosted video from the video's own frames. Every uploaded video gets, shortly after, up to 6 frames across it; `get_media_url` lists them in `coverCandidates`, and `candidate` is the index the person picked. A cover chosen earlier from an image (`set_video_poster`) is deleted. Returns `409` while the frames aren't ready. Who can: the same as `set_video_poster`. *Minimum role: any.*

## `create_drop_description`

Writes the text of a post (`kind: content`, 2 to 4 sentences), a short post (`kind: status`, first person, up to 280 characters) or a comment (`kind: comment`, short, first person) from what the person said in the Drop, in the language spoken, without inventing facts. **Nothing is published**: show the text to the person, then publish it with the same video (`video_media_id`) in [`create_post`](#create-post), [`create_short_post`](#create-short-post) or [`create_comment`](#create-comment). The video is one already uploaded (`media_id`) or a file the person records and hands over now (`video_file_url` or `video_file_base64`, MP4, WebM or MOV, up to 350 MB; for a comment, with `post` and `post_type`). Only whoever recorded the Drop asks (403). `kind: comment` needs the community's `drops_in_comments` setting on (see [`update_community_settings`](/mcp/ferramentas-comunidade)). Up to 10 minutes of speech. Asynchronous: it waits up to `wait_seconds`; while `pending`, use [`get_drop_description`](#get-drop-description). Calling again with the same `media_id` writes a new version (up to 5 per Drop); per-person limits apply (429). See [Drops › Text written by AI](/espacos/drops). With `kind: lesson`, it writes a lesson's text from its Drop (`lesson_id`); the text comes back for the person to review and goes into the lesson with `update_lesson`.

## `get_drop_description`

The state of a `create_drop_description` request (`job_id`): `pending`, `done` (with the text) or `failed` (with the error: `tooLong`, `noSpeech`…). Only whoever asked sees it (404 otherwise); the text stays available for 24 hours.

**Also:** `create_short_post`, `create_post` and `create_comment` take `video_media_id`, to publish with a video already uploaded (the one from `create_drop_description`). On a comment, with `drops_in_comments` off, the Drop is refused before the upload.

## Polls

A question to the community, in a Feed or Content space, with 2 to 10 options. See [Polls](/espacos/enquetes). The tools live on this page, under **Content and engagement**.

| Tool | What it does | Minimum role | Type |
|---|---|---|---|
| `create_poll` | Publishes a poll in a Feed (the question is the text) or in a Content space (the question is the title) | Moderator (not finance) | <span class="tool-kind tool-kind-write">Changes</span> |
| `get_poll` | The results: votes and percentage per option, how many voted, the deadline and what you chose | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| `vote_poll` | Votes in your name, by option id or text; voting again replaces the vote | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| `retract_poll_vote` | Removes your vote while the poll is open | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| `update_poll` | Changes the options, multiple choice and the deadline | Moderator (not finance) | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> when the options change |
| `close_poll` | Closes the poll now, with no way back | Moderator (not finance) | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |
| `list_poll_votes` | Who voted for what, with a filter by option | Moderator (not finance) | <span class="tool-kind tool-kind-read">Read-only</span> |

**Create.** Only in a Feed or Content space; in any other, the tool refuses. `create_poll` takes `space` (id, link, slug or name), `question` (in the Feed, up to 500 characters; in Content, the title), `options` (2 to 10, up to 100 characters each, no repeats), `allow_multiple` (default: one option only), `visibility` (Feed only: `public`, the default, `members` or `plan`; in Content the poll is always public; a `plan` post, for Subscribers, only shows to people with an active subscription and to the team), `closes_at` (ISO 8601 in the future; without it, the poll stays open until `close_poll`) and, in Content only, `details` (text under the question, in Markdown). It does not ask for confirmation. The post goes out with the new-post notification and, like any post, can be pinned with [`pin_post`](#pin-post).

**Finding the poll.** The tools accept in `poll` the poll's id (the `poll.id` returned by [`list_posts`](#list-posts) and `create_poll`) or the id or link of the post that carries it.

**Hidden results.** For someone outside the team who hasn't voted yet, `get_poll` returns `resultsVisible: false` and empty numbers (hidden, not zero) until the poll closes. The team (owner, admin and moderator) always sees them.

**Voting.** `vote_poll` and `retract_poll_vote` act in the name of whoever connected the assistant, without confirmation, because a vote can be changed and removed. In a single-choice poll, one option only. Once closed, both are refused.

**Editing.** `update_poll` takes the full list of `options`, in the new order: `{ id, text }` keeps an option (fixing its text), `{ text }` adds one and an id left out is removed. After the first vote, the options no longer change (neither text nor order: the API returns `409`), and `allow_multiple` is locked. `closes_at: null` removes the deadline. The question is the post's text: change it with [`update_post`](#update-post).

**Closing.** `close_poll` always asks for confirmation and has no way back: nobody votes any more, and everyone sees the final results.

**Ask like this:** *"Create a poll in the Feed asking which month is best for APICON Rio, with March, April and May."* · *"How is the APICON poll going? Who voted for April?"*

**Recipe.** In Claude, **Ask the community (poll)** (`ask_community_poll`) asks for the question, the options, the space (default: the main Feed) and the deadline, creates the poll and follows the results. It shows for the owner, the admin and the moderator.

## Classifieds

The ads that members post in a [Classifieds](/espacos/classificados) space, the interest of the people who respond and moderation. The tools live on this page, under **Content and engagement**.

| Tool | What it does | Minimum role | Type |
|---|---|---|---|
| `get_classifieds_space_settings` | Allowed terms, whether the value shows, whether approval is required and the categories (with the ad count) of a space | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| `update_classifieds_space_settings` | Changes terms, value, approval and the complete category list | Admin | <span class="tool-kind tool-kind-write">Changes</span> |
| `list_classified_ads` | Lists the space's ads (category and text filters) or your own, in any status, with `mine` | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| `get_classified_ad` | One ad, with images, author and what you can do on it | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| `create_classified_ad` | Posts an ad, with images | Whoever can post in the space | <span class="tool-kind tool-kind-write">Changes</span> |
| `update_classified_ad` | Edits your ad and adds or removes images | Author | <span class="tool-kind tool-kind-write">Changes</span> |
| `delete_classified_ad` | Deletes an ad, with its images and interested people | Author, or team (owner, admin, moderator, finance) | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |
| `express_classified_interest` | Sends your interest, with a message | Any (not the author) | <span class="tool-kind tool-kind-write">Changes</span> |
| `list_classified_interests` | Who is interested, with name, message and the account's email and phone | Author, or team | <span class="tool-kind tool-kind-read">Read-only</span> |
| `update_classified_interest_status` | Marks an interest as seen or answered | Author, or team | <span class="tool-kind tool-kind-write">Changes</span> |
| `list_my_classified_interests` | The interests you sent | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| `withdraw_classified_interest` | Withdraws your interest in an ad | Whoever sent it | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |

**Images.** `create_classified_ad` accepts up to 6 images, each by link or in base64; `update_classified_ad` accepts `add_images` and `remove_image_ids`. All are checked before anything changes: an invalid image stops the tool with nothing created.

An ad's new images are stored in a **private area**, with a thumbnail (image by link up to 50 MB, by file up to 5 MB). `list_classified_ads` and `get_classified_ad` return, on each image, `image_url` and `thumbnail_url` for the assistant to look at, with `url_expires_at` and `url_valid_seconds` saying when the link expires (about 1 hour); after that, just ask for the ad again or use [`get_media_url`](#get-media-url). `remove_image_ids` deletes the file.

**Contact.** Before sending an interest, the assistant tells the person that the ad's author and the team (owner, admin, moderator and finance) will see the name, message, and the account's email and phone, and that the platform does not intermediate the deal. It only sends after a yes. The author gets an email without the contact.

**Moderation.** With approval on, `list_moderation_queue` and `moderate_item` accept the `classifieds` type (and `downloads`: approving a Downloads item publishes it at once), also for **finance**, which moderates only this type. Rejecting asks for a reason, and the author gets the decision by email. `create_space` accepts the `classifieds` module.

**Ask like this:** *"Show me who is interested in my bicycle ad and mark the ones I already answered."*

## Channel

The group conversation in a Channel space. They all show up for every role, and Memberfy decides on the spot: the assistant only reads channels the person would open in the app, and only writes and replies where the space's **Who can post** allows. Message text is written by members and reaches the assistant marked as data, never as instructions.

| Tool | What it does | Minimum role | Type |
|---|---|---|---|
| `get_channel_unread` | The unread state of each channel you open: messages, mentions and followed threads with new replies | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| `list_channel_messages` | The channel (whether you can post, react and moderate) and a page of up to 50 messages, with replies, reactions and media | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| `get_channel_thread` | A thread: the message and up to 50 replies | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| `list_channel_mentionable_members` | Who can be mentioned in the channel (from 3 letters), with the `<@id>` token to put in the text | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| `post_channel_message` | Sends a message to the channel; first shows the channel, how many people see it and the text | Whoever can post in the space | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |
| `reply_channel_thread` | Replies in a thread; first shows the channel, the message being answered and the text | Whoever can post in the space | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |
| `update_channel_message` | Edits the text of your message or reply (it shows "(edited)") | Author | <span class="tool-kind tool-kind-write">Changes</span> |
| `delete_channel_message` | Deletes a message or reply ("message deleted" stays; the thread goes on) | Author, or owner, admin and moderator | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |
| `set_channel_reaction` | Adds or takes back your emoji reaction, even without permission to post | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| `follow_channel_thread` | Follows a thread | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| `unfollow_channel_thread` | Unfollows a thread | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| `mark_channel_read` | Marks the channel as read, up to now or up to a message | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| `mark_channel_thread_read` | Marks a thread as read | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| `mute_channel` | Mutes a channel just for you: its mentions and replies stop generating notices and e-mails (unread messages keep counting) | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| `unmute_channel` | Starts receiving the notices of a channel's mentions and replies again | Any | <span class="tool-kind tool-kind-write">Changes</span> |

**Mentions.** To mention someone, the assistant looks the person up with `list_channel_mentionable_members` and writes the `<@id>` token in the text; the name never comes from the assistant. **Limits:** the same as the app (4,000 characters, 30 messages a minute, the same text 3 times an hour); past them, the answer is `429`. [`create_space`](/mcp/ferramentas-comunidade#create-space) accepts `module: "channel"`, and [`update_space_access`](/mcp/ferramentas-comunidade#update-space-access) changes who posts (`can_create`).

**Ask like this:** *"Create a staff-only announcements channel"*, *"What's new in the channels? Any mentions for me?"*, *"Reply in Ana's thread that the meetup is still at 7 pm."* See [recipe 90](/mcp/receitas#90-a-staff-only-announcements-channel).

## Upvote

The topic board in an Upvote space. The reading, voting and commenting tools show up for everyone; the managing ones, for the staff (owner, admin and moderator; not finance). Titles, descriptions and comments reach the assistant marked as data written by members.

| Tool | What it does | Minimum role | Type |
|---|---|---|---|
| `get_upvote_board` | The board: whether you can propose and manage, prior approval and the limits | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| `update_upvote_board` | Turns the board's prior approval on or off | Admin | <span class="tool-kind tool-kind-write">Changes</span> |
| `list_upvote_topics` | The topics, by most voted, newest or trending, with a state filter, yours and the ones you voted for | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| `get_upvote_topic` | A topic, with state, note, votes and comments | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| `find_similar_upvote_topics` | Up to 5 topics similar to a title, before creating | Any | <span class="tool-kind tool-kind-read">Read-only</span> |
| `create_upvote_topic` | Proposes a topic; first shows the board and the text | Whoever can post in the space | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |
| `update_upvote_topic` | Edits the title or description | Author (until someone else votes), or moderator | <span class="tool-kind tool-kind-write">Changes</span> |
| `delete_upvote_topic` | Deletes a topic with its photos | Author (until someone else votes), or moderator | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |
| `vote_upvote_topic` | Votes on the topic, on your behalf | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| `unvote_upvote_topic` | Takes your vote back | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| `create_upvote_comment` | Comments or replies to a comment | Any | <span class="tool-kind tool-kind-write">Changes</span> |
| `delete_upvote_comment` | Deletes a comment and its replies | Author, or moderator | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |
| `list_upvote_voters` | Who voted, with the date they joined the community | Moderator (not finance) | <span class="tool-kind tool-kind-read">Read-only</span> |
| `set_upvote_topic_status` | Changes the state (archiving included, with a reason); shows how many people will be notified | Moderator (not finance) | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |
| `reopen_upvote_topic` | Reopens a Done or Archived topic | Moderator (not finance) | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |
| `merge_upvote_topics` | Merges a repeated topic into the original, taking the votes along; **can't be undone**: the repeated one never reopens | Moderator (not finance) | <span class="tool-kind tool-kind-confirm">Asks to confirm</span> |

[`create_space`](/mcp/ferramentas-comunidade#create-space) accepts `module: "upvotes"`. The limits are the app's (5 topics a day, 120 votes an hour), with `429`.

**Ask like this:** *"Check for a similar topic before creating one"*, *"What are the 5 most voted topics that are still open?"*, *"Move 'Dark mode in the app' to Planned with the note 'coming in March'."* See [recipe 91](/mcp/receitas#91-check-for-a-similar-topic-before-creating-one).

## Related

- [Tools](/mcp/ferramentas)
- [Recipes](/mcp/receitas)
- [Money and confirmation](/mcp/dinheiro-e-confirmacao)
