All loops
SupportMedium 17 min· claude-sonnet-4-5

Zendesk triage trio

Three sub-agents: classifier, drafter, escalator. Sub-second per ticket.

Read the full Support build guide →
NOT DEPLOYEDNOT DEPLOYED
0142ms
Trigger
POST https://hooks.claudeloops.run/zendesk-triage-trio · event=slack.slash:/loop
02802ms
Agent
claude-sonnet-4-5 · in 902 tok · out 230 tok
03192ms
Tools
zendesk-mcp/zendesk:invoke → 200 OK · 222ms
0432ms
Verify
schema check · zod v3 passed
0562ms
Output
zendesk reply drafted · pending review
0622ms
Notify
audit log written · runbook link attached
SUCCESS
0%
0 runs
P50
0ms
median
P95
0ms
tail
AVG COST
per run
LAST OK
never
LAST FAIL
never
none
Latency · last 30 runs0 samples
no runs yet
Latest output · what your users see
Zendesk #5122P2
MCP tool call returns 401 intermittently
macro applied: escalate:billing/no-vat-line
// press Test to run once · Watch live to keep streaming · Deploy to make it real
The problem

Tier-1 support spends most of its day labeling tickets and writing the same five replies.

The outcome

80% of tickets are pre-drafted in the agent UI before tier-1 opens them. Escalations are tagged with a reason and the right specialist.

Ingredients & skills

Secrets
  • ANTHROPIC_API_KEY
  • ZENDESK_TOKEN
  • ZENDESK_WEBHOOK_SECRET
Providers
  • Anthropic
  • Zendesk
MCP servers
  • zendesk-mcp
#support#agents#zendesk

How it works

An MCP webhook from Zendesk hands tickets to a Claude sub-agent router. Three sub-agents handle classify → draft → escalate, in parallel where safe.

Step 1

1 — Router agent

Cheap classifier picks the sub-agent. Don't waste Opus on labeling.

typescript
const route = await haiku.tools.call("route_ticket", { subject, body });
if (route.kind === "billing") return billingAgent.handle(ticket);
if (route.kind === "bug") return bugAgent.handle(ticket);
return defaultAgent.handle(ticket);
Step 2

2 — Drafter writes a private comment

Never post directly to the customer. Always a `public: false` comment for the human to review.

typescript
await zendesk.tickets.update(ticket.id, { comment: { body: draft, public: false }, tags: [...ticket.tags, "ai-drafted"] });
Step 3

3 — Escalator

Sets the assignee group and adds a reason tag the on-call can search.

One-line deploy

The button above runs the same command with your saved config. This is the raw CLI form.

bash
locker deploy zendesk-trio --trigger zendesk-webhook
https://hooks.claudeloops.run/zendesk-triage-trio

Related loops