Read-only zendesk mcp
zendesk-mcp
Read-only MCP server for auditing Zendesk Support tickets and Chat (Zopim) transcripts from Claude.
Why
Fully open-source, GET-only Zendesk MCP — no writes, no side effects, no hidden telemetry. Built for searching, fetching and reading tickets and chat transcripts 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.
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 a Zendesk API token
Admin Center → Apps and integrations → APIs → Zendesk API → enable Token access → Add API token. Copy it (shown once). Note the agent email and subdomain (<sub> in https://<sub>.zendesk.com).
3. Add to Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) and add the zendesk entry under mcpServers:
{
"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": "..."
}
}
}
}
Restart Claude Desktop. For Claude Code, use the same structure in its MCP config.
Tools
Support API
| Name | What it does |
|---|---|
| search_tickets | Search tickets via Zendesk Search (ZQL). Auto-prefixes type:ticket. |
| get_ticket | Ticket metadata (no comments). |
| get_ticket_comments | Full comment history with authors, timestamps, attachments. Auto-paginated. |
| list_views | Active Zendesk views. |
| get_tickets_from_view | Tickets inside a view. |
| list_groups | Support groups. |
Chat API (Zopim)
| Name | What it does |
|---|---|
| get_chat | Single chat session with normalized transcript. |
| search_chats | Search chats by text, timestamp:[X TO Y], or tag:foo. |
| list_chats | Incremental export of chat ids since start_time. |
| get_chat_for_ticket | Resolves the chat that produced a Support ticket — looks up requester, matches by name/email within +/- window_minutes of created_at, returns transcript + candidates. |
All tools return JSON in content[0].text. Chat transcripts are arrays of { type: "message" | "event", author_type, author_name, timestamp, body, ... } — filter type === "message" for conversation turns.
Example prompts
- "For ticket 869955 use
get_chat_for_ticketand score the agent on tone, empathy and resolution." - "Search tickets
status:solved created>2026-04-01 group_id:12345, thenget_ticket_commentsfor each and flag responses lacking empathy." - "Use
list_chatsfor yesterday, thenget_chaton each to find sessions where the agent took >60s to first respond."
Security
- Read-only — only
GETrequests. - Token via env only — never commit;
.envis 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 — wrong token/email, or agent lacks API access. For Chat endpoints, confirm Chat product is enabled.
- 429 — client retries 3x honoring
Retry-After. Lowerper_pageif persistent. - Empty
search_tickets— Zendesk Search has eventual consistency (minutes). - Server missing in
/mcp— confirm absolute paths, runnode dist/index.jsmanually with env vars; should printServer ready on stdio transport.