MCP Reference
Complete reference for Quackback's MCP tools and resources. Parameters, return values, and examples for all 39 tools and 6 resources.
Quackback's MCP server exposes 39 tools and 6 resources. Tools perform actions (search, create, update, delete). Resources provide lookup data (boards, statuses, tags) that tools reference by ID.
Tools
search
Search feedback posts or changelog entries. Returns paginated results with a cursor for the next page.
Parameter | Type | Default | Description |
|---|---|---|---|
|
|
| Entity type to search |
| string | - | Text search across titles and content |
| string | - | Filter posts by board TypeID (ignored for changelogs and articles) |
| string | - | Filter articles by category TypeID (ignored for posts and changelogs) |
| string | - | Filter by status slug. Posts: |
| string[] | - | Filter posts by tag TypeIDs (ignored for changelogs and articles) |
|
|
| Sort order. |
| boolean |
| Show soft-deleted posts (team only, last 30 days) |
| string | - | ISO 8601 date. Filter posts created on or after this date |
| string | - | ISO 8601 date. Filter posts created on or before this date |
| number (1-100) |
| Max results per page |
| string | - | Pagination cursor from a previous response |
Scope: read:feedback for posts and changelogs. read:article + team role for articles (also requires help center to be enabled).
search({ query: "dark mode", sort: "votes", limit: 10 })
search({ entity: "changelogs", status: "published" })
search({ entity: "articles", query: "getting started", status: "published" })
search({ boardId: "board_01abc...", status: "open" })
search({ dateFrom: "2026-01-01", dateTo: "2026-02-01" })
search({ showDeleted: true })get_details
Get full details for any entity by TypeID. The entity type is auto-detected from the ID prefix. No need to specify whether it's a post or changelog.
Parameter | Type | Description |
|---|---|---|
| string | TypeID of the entity (e.g., |
Scope: read:feedback for posts and changelogs. read:article + team role for kb_article_*/kb_category_* (also requires help center to be enabled).
Returns all fields including comments (for posts), linked posts (for changelogs), tags, official response, and timestamps. Also supports kb_article_* and kb_category_* IDs.
get_details({ id: "post_01abc..." })
get_details({ id: "changelog_01xyz..." })
get_details({ id: "kb_article_01abc..." })
get_details({ id: "kb_category_01abc..." })triage_post
Update a post's status, tags, or owner. All fields except postId are optional. Only provided fields are updated.
Parameter | Type | Description |
|---|---|---|
| string | Post TypeID to update |
| string | New status TypeID |
| string[] | Replace all tags with these TypeIDs |
| string | null | Assign to a team member TypeID, or |
Scope: write:feedback + team role (admin or member)
triage_post({ postId: "post_01abc...", statusId: "status_01xyz..." })
triage_post({ postId: "post_01abc...", ownerPrincipalId: "principal_01xyz..." })
triage_post({ postId: "post_01abc...", tagIds: ["tag_01a...", "tag_01b..."] })vote_post
Toggle a vote on a feedback post. Call once to vote, call again to unvote.
Parameter | Type | Description |
|---|---|---|
| string | Post TypeID to vote on |
Scope: write:feedback
Returns the current vote state and total vote count.
vote_post({ postId: "post_01abc..." })proxy_vote
Add or remove a vote on behalf of another user. Use this to record votes from external channels (support tickets, Slack messages, sales calls) with source attribution for traceability.
Parameter | Type | Default | Description |
|---|---|---|---|
|
|
| Whether to add or remove the proxy vote |
| string | - | Post TypeID to vote on |
| string | - | Principal TypeID of the user to vote on behalf of |
| string | - | Attribution source type (e.g. |
| string | - | URL linking to the originating record |
Scope: write:feedback + team role (admin or member)
Adding a vote is idempotent: calling it twice for the same user has no effect. Removing a vote works for any vote type (proxy, integration, or direct).
proxy_vote({ postId: "post_01abc...", voterPrincipalId: "principal_01xyz..." })
proxy_vote({
postId: "post_01abc...",
voterPrincipalId: "principal_01xyz...",
sourceType: "zendesk",
sourceExternalUrl: "https://support.example.com/tickets/1234"
})
proxy_vote({ action: "remove", postId: "post_01abc...", voterPrincipalId: "principal_01xyz..." })add_comment
Post a comment on a feedback post. Supports threaded replies via parentId.
Parameter | Type | Description |
|---|---|---|
| string | Post TypeID to comment on |
| string | Comment text (max 5,000 characters) |
| string | Parent comment TypeID for a threaded reply |
Scope: write:feedback
add_comment({ postId: "post_01abc...", content: "Thanks for the feedback!" })
add_comment({
postId: "post_01abc...",
content: "Good point.",
parentId: "comment_01xyz..."
})update_comment
Edit a comment's content. Team members can edit any comment. Authors can edit their own.
Parameter | Type | Description |
|---|---|---|
| string | Comment TypeID to edit |
| string | New comment text (max 5,000 characters) |
Scope: write:feedback
update_comment({ commentId: "comment_01abc...", content: "Updated response." })delete_comment
Hard-delete a comment and all its replies. This cannot be undone. Authors can delete their own comments. Team members can delete any comment.
Parameter | Type | Description |
|---|---|---|
| string | Comment TypeID to delete |
Scope: write:feedback
Warning:
Deleting a comment also deletes all replies. This action is permanent.
delete_comment({ commentId: "comment_01abc..." })react_to_comment
Add or remove an emoji reaction on a comment.
Parameter | Type | Description |
|---|---|---|
|
| Whether to add or remove the reaction |
| string | Comment TypeID to react to |
| string | Emoji character (e.g., |
Scope: write:feedback
react_to_comment({ action: "add", commentId: "comment_01abc...", emoji: "👍" })
react_to_comment({ action: "remove", commentId: "comment_01abc...", emoji: "👍" })create_post
Submit new feedback on a board. Requires a board ID and title. Content, status, and tags are optional.
Parameter | Type | Description |
|---|---|---|
| string | Board TypeID (use |
| string | Post title (max 200 characters) |
| string | Post body (max 10,000 characters) |
| string | Initial status TypeID (defaults to board default) |
| string[] | Tag TypeIDs to apply |
Scope: write:feedback
Tip:
Use thequackback://boardsresource to look up board IDs before callingcreate_post.
create_post({ boardId: "board_01abc...", title: "Add dark mode" })
create_post({
boardId: "board_01abc...",
title: "Add dark mode",
content: "Would love a dark theme option.",
statusId: "status_01xyz...",
tagIds: ["tag_01a..."]
})delete_post
Soft-delete a feedback post. The post is hidden from public views but can be restored within 30 days.
Parameter | Type | Description |
|---|---|---|
| string | Post TypeID to delete |
Scope: write:feedback + team role (admin or member)
delete_post({ postId: "post_01abc..." })restore_post
Restore a soft-deleted post. Posts can only be restored within 30 days of deletion.
Parameter | Type | Description |
|---|---|---|
| string | Post TypeID to restore |
Scope: write:feedback + team role (admin or member)
restore_post({ postId: "post_01abc..." })merge_post
Merge a duplicate post into a canonical post. Votes are combined. Reversible via unmerge_post.
Parameter | Type | Description |
|---|---|---|
| string | Post TypeID of the duplicate to merge away |
| string | Post TypeID of the canonical post to merge into |
Scope: write:feedback + team role (admin or member)
Tip:
Usesearchto find potential duplicates first, then merge them to consolidate votes.
merge_post({
duplicatePostId: "post_01abc...",
canonicalPostId: "post_01xyz..."
})unmerge_post
Restore a merged post to independent state. Recalculates vote counts for both posts.
Parameter | Type | Description |
|---|---|---|
| string | Post TypeID of the merged post to restore |
Scope: write:feedback + team role (admin or member)
unmerge_post({ postId: "post_01abc..." })create_changelog
Create a changelog entry. Saves as a draft by default. Set publish: true to publish immediately.
Parameter | Type | Default | Description |
|---|---|---|---|
| string | - | Changelog entry title (max 200 characters) |
| string | - | Changelog content, markdown supported (max 50,000 characters) |
| boolean |
| Set to |
Scope: write:changelog + team role (admin or member)
create_changelog({ title: "v2.1 Release", content: "## New features\n- Dark mode..." })
create_changelog({ title: "v2.1 Release", content: "...", publish: true })update_changelog
Update an existing changelog entry's title, content, publish state, or linked posts.
Parameter | Type | Description |
|---|---|---|
| string | Changelog TypeID to update |
| string | New title (max 200 characters) |
| string | New content, markdown supported (max 50,000 characters) |
| boolean |
|
| string[] | Replace linked posts with these post TypeIDs |
Scope: write:changelog + team role (admin or member)
update_changelog({ changelogId: "changelog_01abc...", title: "v2.1.1 Patch" })
update_changelog({
changelogId: "changelog_01abc...",
publish: true,
linkedPostIds: ["post_01a...", "post_01b..."]
})delete_changelog
Soft-delete a changelog entry.
Parameter | Type | Description |
|---|---|---|
| string | Changelog TypeID to delete |
Scope: write:changelog + team role (admin or member)
delete_changelog({ changelogId: "changelog_01abc..." })list_suggestions
List AI-generated feedback suggestions. Suggestions are created when feedback is ingested from external sources (Slack, email, API) and processed by the AI pipeline.
Three suggestion types:
create_post- AI extracted new feedback and suggests creating a postvote_on_post- AI matched feedback to an existing post and suggests adding a voteduplicate_post- AI detected two existing posts that may be duplicates
Parameter | Type | Default | Description |
|---|---|---|---|
|
|
| Filter by suggestion status |
|
| - | Filter by type |
|
|
| Sort order |
| number (1-100) |
| Max results per page |
| string | - | Pagination cursor from a previous response |
Scope: read:feedback + team role (admin or member)
Each suggestion includes the original raw feedback item, matched post (if applicable), AI signal data (summary, evidence, confidence), and source metadata.
list_suggestions()
list_suggestions({ suggestionType: "create_post" })
list_suggestions({ status: "dismissed", sort: "relevance" })accept_suggestion
Accept an AI-generated suggestion. The result depends on the suggestion type:
- create_post: Creates a new post from the extracted feedback. Optional edits override the suggested title, body, or board.
- vote_on_post: Adds a proxy vote to the matched existing post.
- duplicate_post: Merges the source post into the target post. Use
swapDirectionto reverse which post is kept.
Parameter | Type | Description |
|---|---|---|
| string | Suggestion TypeID ( |
| object | Optional. Override |
| boolean | Optional. Reverse merge direction (duplicate_post only) |
Scope: write:feedback + team role (admin or member)
accept_suggestion({ id: "feedback_suggestion_01abc..." })
accept_suggestion({
id: "feedback_suggestion_01abc...",
edits: { title: "Better title" }
})
accept_suggestion({ id: "merge_sug_01abc...", swapDirection: true })dismiss_suggestion
Dismiss an AI-generated suggestion. The suggestion can be restored later via restore_suggestion.
Parameter | Type | Description |
|---|---|---|
| string | Suggestion TypeID ( |
Scope: write:feedback + team role (admin or member)
dismiss_suggestion({ id: "feedback_suggestion_01abc..." })
dismiss_suggestion({ id: "merge_sug_01abc..." })restore_suggestion
Restore a dismissed suggestion back to pending status.
Parameter | Type | Description |
|---|---|---|
| string | Suggestion TypeID ( |
Scope: write:feedback + team role (admin or member)
restore_suggestion({ id: "feedback_suggestion_01abc..." })get_post_activity
Get the activity log for a post. Shows status changes, merges, tag changes, owner assignments, proxy votes, comment pins, and other events in reverse chronological order (limited to the 200 most recent).
Parameter | Type | Description |
|---|---|---|
| string | Post TypeID |
Scope: read:feedback + team role (admin or member)
Each activity entry includes the event type, actor name, metadata (e.g., old/new status), and timestamp.
get_post_activity({ postId: "post_01abc..." })Help Center Tools
Note:
Help center tools are only available when the help center feature flag is enabled. See Help Center for setup.
create_article
Create a new help center article as a draft.
Parameter | Type | Description |
|---|---|---|
| string | Category TypeID to place the article in |
| string | Article title (max 200 characters) |
| string | URL slug (lowercase, hyphens only) |
| string | Article body in Markdown |
| string | Short description for search results and SEO |
Scope: write:article + team role
Articles are created as drafts. Use update_article with publish: true to publish.
update_article
Update an existing help center article. Publish or unpublish by setting the publish parameter.
Parameter | Type | Description |
|---|---|---|
| string | Article TypeID to update |
| string | New title |
| string | New content in Markdown |
| string | New description |
| string | New URL slug |
| string | Move to a different category |
| boolean |
|
Scope: write:article + team role
All fields except articleId are optional. Only provided fields are updated.
delete_article
Soft-delete a help center article.
Parameter | Type | Description |
|---|---|---|
| string | Article TypeID to delete |
Scope: write:article + team role
manage_category
Create, update, or delete a help center category.
Parameter | Type | Description |
|---|---|---|
|
| Operation to perform |
| string | Category TypeID (required for update/delete) |
| string | Category name (required for create) |
| string | URL slug (required for create) |
| string | Category description |
| string | Icon identifier |
| string | Parent category TypeID for nesting |
Scope: write:article + team role
Conversation Tools
Work the support inbox programmatically: list and read conversations, reply to visitors, and change conversation status. All conversation tools require a team role (admin or member) and the support inbox to be enabled.
list_conversations
List support-inbox conversations, newest activity first. Returns a compact, paginated list.
Parameter | Type | Default | Description |
|---|---|---|---|
|
| - | Filter by conversation status |
|
| - | Filter by priority |
| string | - | Filter to a specific assigned agent (principal TypeID) |
| number (1-100) |
| Max results per page |
| string | - | Pagination cursor from a previous response |
Scope: read:chat + team role (admin or member)
list_conversations({ status: "open" })
list_conversations({ assignedAgentPrincipalId: "principal_01xyz...", priority: "high" })get_conversation
Get a conversation and its most recent messages.
Parameter | Type | Default | Description |
|---|---|---|---|
| string | - | Conversation TypeID |
| boolean |
| Include agent-only internal notes |
| string | - | Cursor from a previous response to fetch older messages |
Scope: read:chat + team role (admin or member)
Internal notes are excluded unless includeInternal is true. Anonymous visitors' synthetic emails are never returned.
get_conversation({ conversationId: "conversation_01abc..." })
get_conversation({ conversationId: "conversation_01abc...", includeInternal: true })reply_to_conversation
Send an agent reply in a conversation (visible to the visitor). Auto-assigns the conversation to the calling agent if it's unassigned.
Parameter | Type | Description |
|---|---|---|
| string | Conversation TypeID |
| string | Reply text sent to the visitor (max 4000 characters) |
Scope: write:chat + team role (admin or member)
reply_to_conversation({ conversationId: "conversation_01abc...", content: "Thanks for reaching out, we're on it." })set_conversation_status
Change a conversation's status (open, snoozed, or closed). Snoozing defers it until the customer next replies; closing stamps the resolution time; a later reply reopens it.
Parameter | Type | Description |
|---|---|---|
| string | Conversation TypeID |
|
| New status |
Scope: write:chat + team role (admin or member)
set_conversation_status({ conversationId: "conversation_01abc...", status: "closed" })suggest_post
Suggest to the support team (not the visitor) that a resolved conversation be tracked as a feedback post. Appears only in the agent inbox as an internal note; a team member confirms with one click. Rejected unless the conversation is resolved.
Parameter | Type | Description |
|---|---|---|
| string | Conversation TypeID (must be resolved) |
| string | Suggested board TypeID |
| string | Post title (3-200 characters) |
| string | Post body (max 10,000 characters) |
Scope: write:chat + team role (admin or member)
suggest_post({ conversationId: "conversation_01...", boardId: "board_01...", title: "Add dark mode", content: "Customer asked for a night theme." })share_post
Embed an existing feedback post as a card in the conversation so the visitor can view and upvote it. Use search to find candidates first, to surface related ideas and avoid duplicates.
Parameter | Type | Description |
|---|---|---|
| string | Conversation TypeID |
| string | Post TypeID |
Scope: write:chat + team role (admin or member)
share_post({ conversationId: "conversation_01...", postId: "post_01..." })Ticket Tools
Work the support-ticket surface programmatically: list and read tickets, open new ones, reply, add internal notes, and link tickets to trackers. Tickets share the conversation scopes (read:chat / write:chat). All ticket tools require a team role (admin or member).
Note:
A service (API key) caller sees every ticket; a human caller sees only the tickets their role can view.
list_tickets
List support tickets, most recently updated first. Filter by type, internal status category, customer-facing stage, requester, or company.
Parameter | Type | Default | Description |
|---|---|---|---|
|
| - | Filter by ticket type |
|
| - | Filter by internal status category |
|
| - | Filter by customer-facing public stage |
| string | - | Filter to a requester (principal TypeID) |
| string | - | Filter to a company (company TypeID) |
|
|
| Sort order |
| number (1-100) |
| Max results |
Scope: read:chat + team role (admin or member)
list_tickets({ type: "customer", statusCategory: "open" })
list_tickets({ companyId: "company_01abc..." })get_ticket
Get a ticket and its most recent thread messages, oldest-first.
Parameter | Type | Default | Description |
|---|---|---|---|
| string | - | Ticket TypeID |
| boolean |
| Include internal teammate notes |
| string | - | Message ID cursor from a previous response, to fetch older messages |
Scope: read:chat + team role (admin or member)
get_ticket({ ticketId: "ticket_01abc...", includeInternal: true })create_ticket
Open a support ticket. A description opens the thread. Returns the created ticket.
Parameter | Type | Description |
|---|---|---|
|
| Ticket object type: a requester's request, an internal task, or an umbrella others link to |
| string | Short summary (max 300 characters) |
| string | Opening message body, Markdown (GFM), optional (max 10,000 characters) |
|
| Triage priority (default |
| string | The requester principal TypeID (optional) |
| string | Associated company TypeID (optional) |
Scope: write:chat + team role (admin or member)
create_ticket({ type: "customer", title: "Refund not received", description: "Customer reports a missing refund from last week." })reply_to_ticket
Post a reply on a ticket thread, visible to the requester. Stamps the first-response time on the first reply.
Parameter | Type | Description |
|---|---|---|
| string | Ticket TypeID |
| string | Reply text, Markdown (GFM) (1-10,000 characters) |
Scope: write:chat + team role (admin or member)
reply_to_ticket({ ticketId: "ticket_01abc...", content: "We've issued your refund; it should arrive in 3-5 days." })add_ticket_note
Add an internal note to a ticket thread. The requester never sees it; only the support team does.
Parameter | Type | Description |
|---|---|---|
| string | Ticket TypeID |
| string | Internal note text, Markdown (GFM) (1-10,000 characters) |
Scope: write:chat + team role (admin or member)
add_ticket_note({ ticketId: "ticket_01abc...", content: "Confirmed the refund with billing; awaiting bank processing." })link_ticket
Link a customer ticket to a tracker so the tracker's stage changes cascade onto it. The tracker must be type tracker and the ticket type customer; a customer ticket belongs to at most one tracker.
Parameter | Type | Description |
|---|---|---|
| string | The tracker ticket TypeID |
| string | The customer ticket TypeID to track |
Scope: write:chat + team role (admin or member)
Returns the tracker's linked tickets.
link_ticket({ trackerTicketId: "ticket_01tracker...", ticketId: "ticket_01customer..." })unlink_ticket
Remove a customer ticket from a tracker.
Parameter | Type | Description |
|---|---|---|
| string | The tracker ticket TypeID |
| string | The linked customer ticket TypeID |
Scope: write:chat + team role (admin or member)
Returns the tracker's remaining linked tickets.
unlink_ticket({ trackerTicketId: "ticket_01tracker...", ticketId: "ticket_01customer..." })Resources
Resources provide lookup data for boards, statuses, tags, roadmaps, team members, and help center categories. Use them to find IDs before calling tools like triage_post or create_post.
URI | Returns | Fields | Scope |
|---|---|---|---|
| All boards |
|
|
| All statuses |
|
|
| All tags |
|
|
| All roadmaps |
|
|
| Team members |
|
|
| Help center categories with article counts |
|
|
Tip:
A typical workflow: readquackback://statusesto find the "planned" status ID, then calltriage_postwith that status ID.
Was this helpful?
Your feedback shapes what we write next.