Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

zendesk-mcp

Read-only MCP server for auditing Zendesk Support tickets across all four communication channels - email, Chat (Zopim), Messaging (Sunshine), and Side Conversations.

Why

Fully open-source, GET-only Zendesk MCP — no writes, no side effects, no hidden telemetry. Built for searching, fetching and reading tickets and conversations so an LLM can audit support communication quality. Every tool issues only GET requests; there are no POST/PUT/PATCH/DELETE paths in the codebase.

Channels and how to pick the right tool

Zendesk has four distinct communication channels and each lives behind a different API. Always inspect ticket.via.channel first, then pick the matching tool below.

via.channel Where the conversation lives Tool to use Extra env required
email, web, api, voice Standard ticket comments get_ticket_comments none
chat Zopim Chat API (separate product) get_chat_for_ticket, get_chat, search_chats, list_chats none
native_messaging Sunshine Conversations API get_messaging_conversation (single) or get_messaging_conversations_batch (many) SUNSHINE_APP_ID, SUNSHINE_KEY_ID, SUNSHINE_KEY_SECRET
side_conversation (child) / any parent ticket Side Conversations sub-resource of a parent ticket list_side_conversations, get_side_conversation, get_side_conversations_batch none

side_conversation is a sub-thread attached to a parent ticket (used to consult an internal team or partner). When via.channel="side_conversation" you have the child ticket; the actual SC lives in the parent. There is no global search for side conversations in Zendesk - you must supply a list of parent ticket IDs.

Setup

1. Build

git clone https://github.com/mikhailrojo/zendesk-mcp.git
cd zendesk-mcp
yarn install --immutable
yarn build

Requires Node.js 20+.

2. Get credentials

Zendesk Support API (always required). Admin Center → Apps and integrations → APIs → Zendesk API → enable Token accessAdd API token. Note your agent email and subdomain (<sub> in https://<sub>.zendesk.com).

Sunshine Conversations (only if you use the messaging channel). Admin Center → Apps and integrations → APIs → Conversations API → create a key. Copy key_id and secret. Find the app id in the URL of the key page (24-char hex). Without these env vars the messaging tools return a clear error; the rest still work.

3. Add to Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS). Pick one of two approaches:

Option A - --env-file (recommended). Keep credentials in the project's .env and let Node load them on startup. New env vars in .env are picked up automatically without editing the desktop config again. Requires Node.js 20.6+.

{
  "mcpServers": {
    "zendesk": {
      "command": "/absolute/path/to/node",
      "args": [
        "--env-file=/absolute/path/to/zendesk-mcp/.env",
        "/absolute/path/to/zendesk-mcp/dist/index.js"
      ]
    }
  }
}

Option B - inline env block. Duplicate values into the config:

{
  "mcpServers": {
    "zendesk": {
      "command": "/absolute/path/to/node",
      "args": ["/absolute/path/to/zendesk-mcp/dist/index.js"],
      "env": {
        "ZENDESK_SUBDOMAIN": "yourcompany",
        "ZENDESK_EMAIL": "agent@yourcompany.com",
        "ZENDESK_API_TOKEN": "...",
        "SUNSHINE_APP_ID": "...",
        "SUNSHINE_KEY_ID": "...",
        "SUNSHINE_KEY_SECRET": "..."
      }
    }
  }
}

Restart Claude Desktop (full quit, ⌘Q). For Claude Code use the same structure in its MCP config.

Tools

Tickets (Support API)

Name What it does
search_tickets Search tickets via ZQL. Auto-prefixes type:ticket. Returns metadata only.
get_ticket Single ticket metadata, including via.channel.
get_ticket_comments Comment history for email/web/api channels. Auto-paginated, internal notes excluded by default.
list_views Active Zendesk views.
get_tickets_from_view Tickets inside a view.
list_groups Support groups.

Chat / Zopim (via.channel="chat")

Name What it does
get_chat_for_ticket Primary entry point - resolves the Chat session that produced a Support ticket and returns the transcript + candidates.
get_chat Single chat session by chat_id.
search_chats Search by text, timestamp:[X TO Y], or tag:foo.
list_chats Incremental export of chat ids since start_time.

Messaging / Sunshine (via.channel="native_messaging")

Name What it does
get_messaging_conversation Single ticket's transcript via Sunshine. Picks the conversation closest to ticket time.
get_messaging_conversations_batch Many tickets in parallel. mode="compact" (default) returns per-ticket summary: participants, first user msg, last 3 msgs, counts, language hint - ~10x cheaper in tokens for cross-ticket audits. mode="full" returns all messages in the ticket window. Up to 100 ticket_ids per call.

Side Conversations (via.channel="side_conversation" or any ticket with side threads)

Name What it does
list_side_conversations List SC threads on one parent ticket - metadata only (subject, state, participants, target_ticket_id).
get_side_conversation One SC thread with full event timeline (actor, type, body, recipients, attachments).
get_side_conversations_batch List SCs across many parent tickets in parallel. include_events=true also fetches event timelines. Up to 100 ticket_ids per call.

All tools return JSON in content[0].text.

Example prompts

Single-channel:

  • "For ticket 869955 use get_chat_for_ticket and score the agent on tone, empathy and resolution."
  • "Search tickets status:solved created>2026-04-01 group_id:12345, then get_ticket_comments for each and flag responses lacking empathy."

Cross-ticket audit (use the batch tools):

  • "Search yesterday's messaging tickets with search_tickets query='created>=2026-05-31 channel:native_messaging', then get_messaging_conversations_batch in compact mode to summarize agent tone across the whole day."
  • "For all yesterday's tickets, run get_side_conversations_batch include_events=true to see how agents collaborated with internal teams."

Routing:

  • "Get ticket 875774, check via.channel, then pick the right transcript tool and analyze." (the LLM should branch on the channel value)

Security

  • Read-only — only GET requests.
  • Token via env only — never commit; .env is gitignored.
  • stdout reserved for MCP JSON-RPC; logs go to stderr.
  • PII (customer emails, message text) is intentionally returned to the LLM. Only run against authorized tenants.
yarn audit            # yarn audit + trivy

Troubleshooting

  • 401 from Zendesk — wrong token/email, or agent lacks API access.
  • 401 from Sunshine (invalid_auth) — wrong SUNSHINE_* env. Check SUNSHINE_KEY_ID vs SUNSHINE_KEY_SECRET (the tool also accepts the legacy name SUNSHINE_SECRET_KEY).
  • 429 — client retries 3x honoring Retry-After. Lower per_page / concurrency if persistent.
  • Empty search_tickets — Zendesk Search has eventual consistency (minutes).
  • No conversations found from messaging tool — the requester's account predates the messaging integration, or the ticket was not actually native_messaging. Double-check via.channel.
  • Server missing in /mcp — confirm absolute paths, run node dist/index.js manually with env vars; should print Server ready on stdio transport (sunshine=on) (or off).

About

Read-only zendesk mcp

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages