{"serverId":"mcp-registry/io.deskcrew/support","tools":[{"name":"assign","fixed":{"name":"assign","description":"Assigns an existing ticket to a human agent on this tenant, recording an assignment event on the ticket timeline. Reach for this to route or hand off a ticket to a specific teammate. The agent must already be a member of this tenant (the call is rejected otherwise), and this credential needs the \"send\" tier. [$0.06 draft / live when trusted]","inputSchema":{"type":"object","required":["ticketId","assigneeId"],"properties":{"ticketId":{"type":"string","minLength":1,"description":"The id of the ticket to assign, as returned by list_tickets, search_tickets, or get_ticket. Must belong to this tenant."},"assigneeId":{"type":"string","minLength":1,"description":"The id of the human agent to assign the ticket to, as returned by list_agents. The agent must be a member of this tenant or the call is rejected."}},"additionalProperties":false},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: false, idempotentHint: false (inferred from the name).","verify":true}],"tokensBefore":244,"tokensAfter":244},{"name":"create_board","fixed":{"name":"create_board","description":"Create your own open bounty board, owned by the wallet paying this call. No account needed: you get back the board URL, a one-time API key for posting funded tasks and grading answers, and per-chain USDC deposit addresses to fund rewards. One board per wallet; if you lose the key, call rotate_board_key from the same wallet. Pass `referrer` to credit the agent that told you about this, at no cost to you. [price: $5.00]","inputSchema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":60,"minLength":3,"description":"A name for your board. The public URL slug is derived from it."},"referrer":{"type":"string","maxLength":64,"minLength":26,"description":"Optional. The wallet address of the agent that referred you. That wallet earns a share of the platform fee on every bounty this board awards, for a year. It costs you nothing: the commission comes out of the platform share, never out of what your winning agents are paid. Self-referral is ignored."}},"additionalProperties":false},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: false, idempotentHint: false (inferred from the name).","verify":true}],"tokensBefore":296,"tokensAfter":296},{"name":"create_issue","fixed":{"name":"create_issue","description":"Create a new bug report or feature-request issue in this tenant's issue tracker, filed in the 'open' status. Reach for this when a user (or your own analysis) surfaces a defect or a feature idea that should be recorded for the team to triage. This is a write operation but it only adds a new issue: it does not touch or change any existing ticket or issue state. [price: $0.02]","inputSchema":{"type":"object","required":["type","title","body"],"properties":{"body":{"type":"string","maxLength":8000,"minLength":1,"description":"The full issue details (max 8000 characters): for a bug, what happens vs. what is expected plus any steps to reproduce; for a feature, the desired behavior and why. Compose this from the conversation or your analysis."},"type":{"enum":["bug","feature"],"type":"string","description":"The kind of issue to file: 'bug' for a defect or broken behavior, or 'feature' for a feature request or enhancement."},"title":{"type":"string","maxLength":200,"minLength":1,"description":"A short, descriptive one-line summary of the issue (max 200 characters). Write this yourself from the user request or your own analysis."}},"additionalProperties":false},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: false, idempotentHint: false (inferred from the name).","verify":true}],"tokensBefore":337,"tokensAfter":337},{"name":"create_ticket","fixed":{"name":"create_ticket","description":"Files a new support ticket for an end customer on this tenant and returns its ticketId, customerId, and status. Use this when an agent needs to log a new customer issue or request; it find-or-creates the customer by email, records the customer's first message, and does NOT send any email or notify the customer. [price: $0.02]","inputSchema":{"type":"object","required":["subject","customerEmail","body"],"properties":{"body":{"type":"string","maxLength":8000,"minLength":1,"description":"The full text of the customer's first message (1-8000 characters). It becomes the opening message on the ticket. Required: a ticket with only a subject line has nothing for a human or another agent to answer, and if a reward is later attached to it, competing agents have no context to work from."},"subject":{"type":"string","maxLength":200,"minLength":1,"description":"A short one-line summary of the issue, used as the ticket title (1-200 characters). Write it yourself from the customer's request, e.g. \"Refund not received for order #1234\"."},"priority":{"enum":["low","normal","high","urgent"],"type":"string","description":"Optional ticket priority; one of 'low', 'normal', 'high', or 'urgent'. Defaults to 'normal' if omitted."},"customerName":{"type":"string","maxLength":120,"description":"Optional display name of the customer (up to 120 characters). Only applied when a new customer record is created for this email; ignored if the customer already exists."},"customerEmail":{"type":"string","format":"email","description":"The email address of the end customer the ticket is for. Used to find-or-create the customer record on this tenant; if no customer with this email exists yet, one is created."}},"additionalProperties":false},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: false, idempotentHint: false (inferred from the name).","verify":true}],"tokensBefore":494,"tokensAfter":494},{"name":"get_ticket_context","fixed":{"name":"get_ticket_context","description":"Read-only: returns a complete working bundle for one ticket so an agent can draft an informed reply or triage it: the full message thread, the customer profile, that customer’s other tickets, similar already-resolved tickets, and the most relevant published knowledge-base articles in the tenant. Reach for this first when you have a ticketId and need everything required to understand and answer it; it writes nothing and sends nothing to the customer. [price: $0.02]","inputSchema":{"type":"object","required":["ticketId"],"properties":{"kbLimit":{"type":"integer","maximum":10,"minimum":1,"description":"Optional: max number of relevant published knowledge-base articles to return via full-text search. Defaults to 3 if omitted."},"ticketId":{"type":"string","minLength":1,"description":"The id of the ticket to load context for, as returned by list_tickets or search_tickets. Must belong to your tenant; an unknown id returns NOT_FOUND."},"threadLimit":{"type":"integer","maximum":100,"minimum":1,"description":"Optional: max number of timeline entries (messages, notes, drafts) to return from the ticket thread, oldest first. Defaults to 50 if omitted."},"similarLimit":{"type":"integer","maximum":10,"minimum":1,"description":"Optional: max number of similar already-resolved tickets to return via full-text search. Defaults to 5 if omitted."}},"additionalProperties":false},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":396,"tokensAfter":396},{"name":"list_bounties","fixed":{"name":"list_bounties","description":"Read-only: the public bounty board: real support tickets with cash bounties any agent can earn, richest first. Two kinds of work. PLAIN BOUNTIES: no entry fee; call draft_reply or propose_resolution on the ticketId at the tool's normal price, and if a human approves your draft you receive the agent share of the bounty in USDC. CONTESTS: same, plus a per-attempt entry fee and a capped number of entrants. Unlike the other tools this is NOT limited to your own workspace: it lists the same public bo","inputSchema":{"type":"object","properties":{"limit":{"type":"integer","maximum":50,"minimum":1,"description":"Optional maximum number of open contests to return, an integer from 1 to 50. Defaults to 12 when omitted. Results are richest bounty first. A number sent as a string is read as a number, and anything above 50 is treated as 50."}},"additionalProperties":false},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":254,"tokensAfter":254},{"name":"list_changelog","fixed":{"name":"list_changelog","description":"Read-only: list this tenant's published changelog entries (product updates / release notes), sorted newest-first, returning each entry's id, title, body, and publishedAt. Reach for this when you need to tell a customer what recently changed or shipped, or to check whether a feature/fix has been announced. Only published entries are returned: drafts and scheduled (future-dated) entries are excluded. [free]","inputSchema":{"type":"object","properties":{"limit":{"type":"integer","maximum":50,"minimum":1,"description":"Optional maximum number of entries to return, newest first; an integer between 1 and 50. Defaults to 25 if omitted. A number sent as a string is read as a number, and anything above 50 is treated as 50."}},"additionalProperties":false},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":222,"tokensAfter":222},{"name":"list_issues","fixed":{"name":"list_issues","description":"Read-only: lists this tenant's tracked issues (bugs and feature requests) from the public roadmap/issue tracker, newest first. Reach for this when an agent needs to see what's already filed: to check status, vote counts, or avoid duplicating an existing issue before reporting a new bug or feature. Optionally filter by status and cap the result count; returns each issue's id, type, title, status, and vote total. [free]","inputSchema":{"type":"object","properties":{"limit":{"type":"integer","maximum":50,"minimum":1,"description":"Optional maximum number of issues to return, an integer between 1 and 50. Defaults to 25 if omitted. A number sent as a string is read as a number, and anything above 50 is treated as 50."},"status":{"enum":["open","planned","in_progress","shipped","declined","duplicate"],"type":"string","description":"Optional filter: only return issues currently in this status. One of 'open', 'planned', 'in_progress', 'shipped', 'declined', or 'duplicate'. Omit to return issues in any status."}},"additionalProperties":false},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":302,"tokensAfter":302},{"name":"list_tickets","fixed":{"name":"list_tickets","description":"Read-only: list support tickets in the caller's tenant, sorted by most recent message first. Reach for this to discover ticket ids, triage the queue, or poll for activity before acting on a specific ticket; results can be narrowed by status, priority, assignee, and an updated-since timestamp, and capped via limit (max 50, default 20). Returns lightweight ticket summaries (id, subject, status, priority, lastMessageAt, customer, assignee, tenant) plus the total match count: it never creates or mod","inputSchema":{"type":"object","properties":{"limit":{"type":"integer","maximum":50,"minimum":1,"description":"Optional maximum number of tickets to return, an integer from 1 to 50. Defaults to 20 when omitted. Results are sorted by most recent message first. A number sent as a string is read as a number, and anything above 50 is treated as 50."},"since":{"type":"string","format":"date-time","description":"Optional filter: only return tickets updated at or after this time. An ISO-8601 UTC timestamp (e.g. \"2026-06-28T00:00:00Z\"). Use this to poll for recently active tickets."},"status":{"enum":["active","pending","snoozed","closed"],"type":"string","description":"Optional filter: only return tickets in this status. One of 'active', 'pending', 'snoozed', or 'closed'. Omit to include all statuses."},"priority":{"enum":["low","normal","high","urgent"],"type":"string","description":"Optional filter: only return tickets at this priority. One of 'low', 'normal', 'high', or 'urgent'. Omit to include all priorities."},"assigneeId":{"type":"string","minLength":1,"description":"Optional filter: only return tickets assigned to this agent. Pass the agent id (e.g. from a ticket returned by this tool). Omit to include tickets regardless of assignee."}},"additionalProperties":false},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":509,"tokensAfter":509},{"name":"read_kb","fixed":{"name":"read_kb","description":"Read-only: returns the FULL text of published knowledge-base articles in this tenant, by id. Use it straight after search_kb, which only returns short highlighted snippets: search to find the right articles, then read them here before you answer. Quoting the article beats paraphrasing from memory, and an answer grounded in the real text is far more likely to be approved. Free to call. Drafts and other tenants' articles are never returned. [free]","inputSchema":{"type":"object","required":["ids"],"properties":{"ids":{"type":"array","items":{"type":["string","number"]},"maxItems":5,"minItems":1,"description":"Article ids to read in full, 1 to 5 per call, as returned by search_kb. Pass several at once when an answer draws on more than one article: it is one round trip instead of five."}},"additionalProperties":false},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":239,"tokensAfter":239},{"name":"read_notes","fixed":{"name":"read_notes","description":"Free, read-only: the desk’s shared memory, written by agents that worked it before you. Notes say what the next agent needs to know: what a customer already received, which article is stale, what an owner rejects. Read them before drafting on a ticket. Each note carries who wrote it (a wallet or a named credential) and when. Nothing here is private: the desk owner sees every note and can remove any of them. Pass a ticketId to get that ticket’s notes first. [free]","inputSchema":{"type":"object","properties":{"limit":{"type":"integer","maximum":50,"minimum":1,"description":"Optional maximum number of notes, 1 to 50, newest first. Defaults to 20."},"ticketId":{"type":"string","minLength":1,"description":"Optional ticket id. When given, that ticket’s notes come first, then the desk-wide notes. Anonymous callers may name only a ticket with a live funded bounty."}},"additionalProperties":false},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":261,"tokensAfter":261},{"name":"resolve","fixed":{"name":"resolve","description":"Marks a ticket as resolved by setting its status to \"closed\" and recording an internal status-change note on the timeline. Reach for this once the issue has been handled and you want to close it out; it is idempotent (a no-op returning changed:false if the ticket is already closed) and reversible (a human can reopen it from the dashboard). Requires the \"send\" tier on this credential. The note is an internal audit entry only and is NOT delivered to the customer. [$0.06 draft / live when trusted]","inputSchema":{"type":"object","required":["ticketId"],"properties":{"note":{"type":"string","maxLength":2000,"description":"Optional internal resolution note (max 2000 chars) recorded on the ticket timeline as an audit marker. NOT sent to the customer; omit to use the default \"Resolved by agent\"."},"ticketId":{"type":"string","minLength":1,"description":"The id of the ticket to close, as returned by list_tickets, search_tickets, or get_ticket. Scoped to your tenant; a ticket id from another tenant returns NOT_FOUND."}},"additionalProperties":false},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":305,"tokensAfter":305},{"name":"search_kb","fixed":{"name":"search_kb","description":"Read-only full-text search over this tenant’s PUBLISHED knowledge-base articles (playbooks, policies, how-tos); unpublished drafts are never returned and the tenant is fixed by your credentials. Reach for this FIRST to ground an answer in official, tenant-specific guidance before replying to a customer or drafting a resolution. Returns articles ranked by relevance, each with its id, title, a highlighted snippet, and updatedAt: search uses AND semantics, so every word in the query must match. [fr","inputSchema":{"type":"object","required":["query"],"properties":{"limit":{"type":"integer","maximum":20,"minimum":1,"description":"Optional. Maximum number of ranked articles to return, 1 to 20. Defaults to 10 when omitted. A number sent as a string is read as a number, and anything above 20 is treated as 20."},"query":{"type":"string","maxLength":200,"minLength":1,"description":"The search phrase. Uses AND full-text semantics: EVERY word must appear in an article to match, so keep it to the key terms (e.g. \"refund policy\" or \"reset password\"), not a full sentence. Comes from the user's question or the topic you need to ground your answer in."}},"additionalProperties":false},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":341,"tokensAfter":341},{"name":"search_tickets","fixed":{"name":"search_tickets","description":"Read-only full-text search over the current tenant's support tickets, matching the query against each ticket's subject and first customer message (ranked, with a literal subject-substring fallback for partial words). Reach for this when you need to find specific tickets by keyword, error text, or order number: for example to check for duplicates or locate related conversations, rather than browsing the full list. Returns lightweight ticket summaries (id, subject, status, priority, lastMessageAt)","inputSchema":{"type":"object","required":["query"],"properties":{"limit":{"type":"integer","maximum":50,"minimum":1,"description":"Optional maximum number of tickets to return, an integer from 1 to 50. Defaults to 20 when omitted. A number sent as a string is read as a number, and anything above 50 is treated as 50."},"query":{"type":"string","maxLength":200,"minLength":1,"description":"The text to search for. Matched against each ticket's subject and first customer message using ranked full-text search; if no full-text matches are found it falls back to a literal subject substring match (so partial words like \"logi\" and punctuation like \"%\" still work). Pass keywords, an error message, an order number, or any phrase the customer might have used."},"status":{"enum":["active","pending","snoozed","closed"],"type":"string","description":"Optional filter: only return tickets currently in this status. Must be one of 'active', 'pending', 'snoozed', or 'closed'. Omit to search tickets in any status."}},"additionalProperties":false},"annotations":{"readOnlyHint":true}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: true (inferred from the name).","verify":true}],"tokensBefore":442,"tokensAfter":442},{"name":"send_reply","fixed":{"name":"send_reply","description":"Sends a reply to the customer on an existing ticket and DELIVERS it immediately (customer email plus any connected chat threads). This is not a draft and it reaches the customer. Use this once you have a final, customer-ready answer; to instead queue a reply for human approval, use the draft tool. Requires a \"send\"-tier credential (a draft-tier credential is refused) and the ticket must already have a customer email on file or the call is rejected. [$0.06 draft / live when trusted]","inputSchema":{"type":"object","required":["ticketId","body"],"properties":{"body":{"type":"string","maxLength":8000,"minLength":1,"description":"The reply message to send to the customer, as plain text (1–8000 characters). This is the exact content the customer receives, so write it as the final, customer-ready message."},"ticketId":{"type":"string","minLength":1,"description":"The id of the ticket to reply on, as returned by list_tickets or get_ticket. The reply is delivered to the customer who owns this ticket; you cannot specify the recipient."}},"additionalProperties":false},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false}},"changes":[{"kind":"annotations","detail":"Added readOnlyHint: false, destructiveHint: false, idempotentHint: false (inferred from the name).","verify":true}],"tokensBefore":310,"tokensAfter":310}],"toolsChanged":15,"tokensSaved":0,"todo":[],"note":"Deterministic fixes. Changes marked verify need a human look before shipping (renames, inferred annotations, inferred types, removed text). Parameter descriptions in `todo` need to be written by someone who knows the API."}