zendesk_apply_macro
Apply a macro to a Zendesk ticket, updating fields and posting a comment. Returns the applied changes and comment details.
Instructions
Apply a macro to a Zendesk ticket. Fetches the macro preview, applies field changes, and posts any comment included in the macro. Returns JSON with id, status, tags, applied_changes, comment_added.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| ticket_id | Yes | ||
| macro_id | Yes |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- src/zendesk_mcp/tools/macros.py:113-116 (handler)The MCP tool handler function that applies a macro to a Zendesk ticket. Decorated with @mcp.tool() and delegates to _apply_macro_data().
@mcp.tool() def zendesk_apply_macro(ticket_id: int, macro_id: int) -> str: """Apply a macro to a Zendesk ticket. Fetches the macro preview, applies field changes, and posts any comment included in the macro. Returns JSON with id, status, tags, applied_changes, comment_added.""" return _apply_macro_data(ticket_id, macro_id) - The core implementation of zendesk_apply_macro. Calls Zendesk's apply endpoint via httpx, then applies ticket field changes and/or posts a comment via the Zenpy client.
def _apply_macro_data(ticket_id: int, macro_id: int) -> str: try: subdomain, token = get_oauth_session() except ConfigError as e: return str(e) url = f"https://{subdomain}.zendesk.com/api/v2/tickets/{ticket_id}/macros/{macro_id}/apply.json" try: response = httpx.get(url, headers={"Authorization": f"Bearer {token}"}, timeout=30) response.raise_for_status() result = response.json().get("result", {}) except Exception as e: if "404" in str(e): return f"Ticket #{ticket_id} or Macro #{macro_id} not found or not accessible with current credentials." return f"Zendesk API error: {e}" ticket_changes = {k: v for k, v in (result.get("ticket") or {}).items() if k not in _SKIP_TICKET_FIELDS} comment_data = result.get("comment") or {} applied_changes = {} comment_added = False # Note: the field update and comment post are two separate API calls, so # if the comment fails after the field update succeeds, the ticket is left # in a partially-mutated state and the caller sees a generic error. try: client = get_client() if ticket_changes: ticket = client.tickets(id=ticket_id) for k, v in ticket_changes.items(): setattr(ticket, k, v) client.tickets.update(ticket) applied_changes = ticket_changes if comment_data and (comment_data.get("body") or comment_data.get("html_body")): body = comment_data.get("body") or comment_data.get("html_body", "") public = comment_data.get("public", True) comment_ticket = ZenpyTicket(id=ticket_id) comment_ticket.comment = Comment(body=body, public=public) client.tickets.update(comment_ticket) comment_added = True refreshed = client.tickets(id=ticket_id) return json.dumps({ "id": refreshed.id, "status": refreshed.status, "tags": list(getattr(refreshed, "tags", []) or []), "applied_changes": applied_changes, "comment_added": comment_added, }, indent=2) except ConfigError as e: return str(e) except Exception as e: if "RecordNotFound" in str(e) or "404" in str(e): return f"Ticket #{ticket_id} not found or not accessible with current credentials." return f"Zendesk API error: {e}" - src/zendesk_mcp/server.py:46-50 (registration)Registration of macro tools (including zendesk_apply_macro) via register_macro_tools(mcp) call in the main() function.
register_macro_tools(mcp) register_user_tools(mcp) register_group_tools(mcp) register_organization_tools(mcp) register_custom_status_tools(mcp) - src/zendesk_mcp/tools/macros.py:6-6 (schema)Set of ticket fields skipped when applying changes (id, url, created_at, updated_at). These are metadata fields returned by the preview that should not be applied back to the ticket.
_SKIP_TICKET_FIELDS = {"id", "url", "created_at", "updated_at"}