npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@markusvankempen/zendesk-mcp-server

v1.0.2

Published

Zendesk MCP server — 14 support ticket tools for AI agents. Cursor, VS Code, Claude Desktop, watsonx Orchestrate, IBM Code Engine SSE.

Readme

@markusvankempen/zendesk-mcp-server

npm npm downloads License Node.js VS Code Extension MCP Registry

TypeScript MCP server for Zendesk support operations — 14 tools for AI agents to create, search, assign, comment, and close tickets with correct customer requester attribution.

mcp · zendesk · cursor · claude · github-copilot · ai-agents · customer-support · typescript

Author: Markus van Kempen
Email: [email protected] · [email protected]
Website: markusvankempen.github.io
No bug too small, no syntax too weird.


Table of contents


What it does

This server exposes 14 Zendesk API operations as MCP tools that any MCP-compatible AI agent can call. The most important feature is correct ticket requester attribution: when create_ticket is called, the server looks up or creates the actual customer user in Zendesk and sets them as the ticket requester — not the API service account. This ensures Zendesk reply emails route to the customer inbox.

The server supports two transports:

  • stdio (default) — spawn as child process by IDE or WxO
  • SSE — run as HTTP server for remote clients (IBM Code Engine)

Install

# Via npx (no install needed — recommended for mcp.json)
npx -y @markusvankempen/zendesk-mcp-server

# Global install
npm install -g @markusvankempen/zendesk-mcp-server
zendesk-mcp-server

# As project dependency
npm install @markusvankempen/zendesk-mcp-server

Requires Node.js 18 or later.


Environment variables

| Variable | Required | Default | Description | |----------|----------|---------|-------------| | ZENDESK_SUBDOMAIN | Yes | — | Your Zendesk tenant prefix. mycompanymycompany.zendesk.com | | ZENDESK_EMAIL | Yes | — | Service account email used for API authentication | | ZENDESK_API_TOKEN | Yes | — | Zendesk API token (Settings → Channels → API) | | MCP_TRANSPORT | No | stdio | Set to sse to start an HTTP server instead of stdio | | PORT | No | 8080 | HTTP port for SSE mode | | HOST | No | 0.0.0.0 | HTTP bind address for SSE mode |

Getting a Zendesk API token:

  1. Log in to your Zendesk Admin UI
  2. Go to Admin → Apps and Integrations → APIs → Zendesk API
  3. Enable Token Access
  4. Click "Add API token"
  5. Copy the token (shown only once)

Quick start — Cursor

Add to ~/.cursor/mcp.json (global) or <project>/.cursor/mcp.json (project-level):

{
  "mcpServers": {
    "zendesk-mcp": {
      "command": "npx",
      "args": ["-y", "@markusvankempen/zendesk-mcp-server"],
      "env": {
        "ZENDESK_SUBDOMAIN": "mycompany",
        "ZENDESK_EMAIL": "[email protected]",
        "ZENDESK_API_TOKEN": "xxxxxxxxxxxxxxxxxxxx"
      }
    }
  }
}

Restart Cursor after saving. The server will appear in the MCP tools panel. You can now ask Cursor:

  • "Create a support ticket for [email protected] about a login issue"
  • "Show me all open high-priority tickets"
  • "What are the SLA metrics for ticket 42?"

Tip: Install the VS Code extension to manage this config file automatically with secure credential storage.


Quick start — Claude Desktop

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "zendesk-mcp": {
      "command": "npx",
      "args": ["-y", "@markusvankempen/zendesk-mcp-server"],
      "env": {
        "ZENDESK_SUBDOMAIN": "mycompany",
        "ZENDESK_EMAIL": "[email protected]",
        "ZENDESK_API_TOKEN": "xxxxxxxxxxxxxxxxxxxx"
      }
    }
  }
}

Restart Claude Desktop after saving.


Quick start — VS Code

Using the VS Code extension (recommended):

  1. Install zendesk-mcp-vscode from VS Marketplace or Open VSX
  2. Run command Zendesk MCP: Configure Credentials
  3. Enter subdomain, email, and API token
  4. The extension writes mcp.json automatically

Manual setup — add to VS Code settings.json:

{
  "mcp.servers": {
    "zendesk-mcp": {
      "command": "npx",
      "args": ["-y", "@markusvankempen/zendesk-mcp-server"],
      "env": {
        "ZENDESK_SUBDOMAIN": "mycompany",
        "ZENDESK_EMAIL": "[email protected]",
        "ZENDESK_API_TOKEN": "xxxxxxxxxxxxxxxxxxxx"
      }
    }
  }
}

Tools available

All 14 tools are registered automatically on startup. See docs/reference/TOOLS.md for full documentation of each tool including parameters, return JSON, error cases, and usage examples.

| Tool | What it does | |------|-------------| | create_ticket | Create ticket with correct customer requester attribution | | get_ticket | Get full ticket details by ID | | update_ticket | Change status, priority, tags, or add a comment | | search_tickets | Search with Zendesk query syntax | | list_recent_tickets | Most recently updated tickets | | list_all_tickets | Admin-wide listing with optional status filter | | list_tickets_for_requester | All tickets owned by a specific customer email | | get_ticket_comments | Full conversation history (public + internal) | | add_ticket_comment | Post a reply or internal note | | get_user_by_email | Look up a Zendesk user record | | close_ticket | Mark a ticket as solved | | reopen_ticket | Reopen a solved/closed ticket | | get_ticket_metrics | SLA and timing metrics | | assign_ticket | Assign to a group and/or specific agent |


SSE mode — IBM Code Engine / remote

Run as an HTTP server for remote MCP clients:

ZENDESK_SUBDOMAIN=mycompany \
[email protected] \
ZENDESK_API_TOKEN=xxxx \
MCP_TRANSPORT=sse \
PORT=8080 \
zendesk-mcp-server

SSE endpoints

| Path | Method | Description | |------|--------|-------------| | GET /sse | GET | Opens a persistent SSE stream. Response stays open. Server sends event: endpoint with data: /message?sessionId=<uuid>. | | POST /message?sessionId=<id> | POST | Send a JSON-RPC request. Response arrives via the SSE stream. | | GET /health | GET | Returns 200 ok. Used by load balancers and Code Engine health probes. |

Remote MCP client configuration

{
  "mcpServers": {
    "zendesk-mcp-remote": {
      "url": "https://your-app.us-south.codeengine.appdomain.cloud/sse"
    }
  }
}

Note: URL-based MCP server config requires an MCP client that supports SSE transport. Cursor supports this in recent versions.

Test SSE locally

# Terminal 1 — start server
MCP_TRANSPORT=sse PORT=8080 ZENDESK_SUBDOMAIN=x [email protected] ZENDESK_API_TOKEN=x \
  zendesk-mcp-server

# Terminal 2 — test health
curl http://localhost:8080/health
# → ok

# Terminal 3 — open SSE stream (stays open)
curl -N -H "Accept: text/event-stream" http://localhost:8080/sse
# → event: endpoint
# → data: /message?sessionId=abc123

See deployments/code-engine/README.md for full IBM Code Engine deployment.


Distribution

This package is published to npm. Do not clone GitHub to run the server — use npx:

npx -y @markusvankempen/zendesk-mcp-server

Server source is maintained in a private development repository. See docs/PUBLIC_REPO.md.


Package layout (npm tarball)

@markusvankempen/zendesk-mcp-server/
├── bin/
│   └── zendesk-mcp-server.js    # CLI shim — #!/usr/bin/env node
├── dist/                        # Compiled JavaScript
├── package.json                 # npm package manifest with bin entry
└── tsconfig.json                # TypeScript compiler config

How the server works

Startup sequence

1. Load ZendeskConfig (ZENDESK_SUBDOMAIN / EMAIL / API_TOKEN)
   → Throws immediately if any are missing
2. Create McpServer({ name: "zendesk-mcp", version: "1.0.0" })
3. Register all 14 tools via registerTicketTools(server)
4. Read MCP_TRANSPORT from environment
5a. stdio: create StdioServerTransport → server.connect(transport)
5b. sse:   create http.createServer with /health, /sse, /message routes
          → server.listen(PORT, HOST)

Credential handling

ZENDESK_EMAIL + ZENDESK_API_TOKEN
→ `${email}/token:${token}`
→ base64 encode
→ Authorization: Basic <encoded>

This header is attached to every outgoing REST call inside authHeaders() in zendesk-client.ts.

Per-request call graph for create_ticket

LLM → MCP client → JSON-RPC tools/call create_ticket
  → TypeScript handler:
      1. validateEmail(requester_email) — if false: return jsonError
      2. zendeskFetch GET /users/search.json?query={email}
         → if found: extract users[0].id
         → if empty: zendeskFetch POST /users.json → get new id
      3. zendeskFetch POST /tickets.json { requester_id: id, ... }
      4. return jsonResult({ ticket_id, ticket_url, requester_email, subject, status })

Requester attribution

This is the most important design decision. When an AI agent creates a Zendesk ticket using a service account, Zendesk defaults the requester to the service account — meaning all reply emails go to the bot inbox instead of the customer.

This server solves it by:

  1. Accepting requester_email as a required parameter in create_ticket
  2. Looking up the customer in Zendesk by email
  3. Creating the customer as a Zendesk user if they don't exist (with verified: true)
  4. Setting requester_id on the ticket to the customer's Zendesk user ID

The service account credentials appear only in the Authorization header. The customer's identity is explicit in the ticket data.


Error handling

All tools catch exceptions and return JSON error objects — no tool ever crashes the MCP server process or throws an unhandled exception at the protocol level:

{ "error": "404 Not Found — Couldn't find Ticket with 'id'=99999" }

Error sources:

  • Missing required parameters → validated before any API call
  • Invalid email format → validated with regex before any API call
  • Zendesk HTTP errors (401, 403, 404, 422, 429) → status code + body text
  • Network errors → exception message

Verify tool registration

After install, verify all 14 tools are registered:

ZENDESK_SUBDOMAIN=test [email protected] ZENDESK_API_TOKEN=test \
  node --input-type=module <<'EOF'
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";

const transport = new StdioClientTransport({
  command: "npx",
  args: ["-y", "@markusvankempen/zendesk-mcp-server"],
  env: { ...process.env }
});
const client = new Client({ name: "verify", version: "1.0.0" });
await client.connect(transport);
const { tools } = await client.listTools();
console.log(`Tools registered: ${tools.length}`);
tools.forEach(t => console.log(` - ${t.name}`));
await client.close();
EOF

Expected: 14 tools listed.


Troubleshooting

"Cannot find module" on startup

Ensure you have built the project: npm run build in packages/zendesk-mcp-server/. The dist/ directory must exist.

"ZENDESK_SUBDOMAIN is not set"

The server validates credentials at startup. Check that your mcp.json env block contains all three required variables.

Tool calls return 401 Unauthorized

Your ZENDESK_API_TOKEN is invalid or expired. To test:

curl -s -u "${ZENDESK_EMAIL}/token:${ZENDESK_API_TOKEN}" \
  "https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets/recent.json"

Tool calls return 404 for ticket IDs

The ticket ID does not exist in your Zendesk subdomain. Verify you are connecting to the correct subdomain.

SSE mode: clients connect but tool calls hang

Check that MCP_TRANSPORT=sse is set correctly. In stdio mode the server reads from stdin — there is no HTTP server. In SSE mode POST requests to /message?sessionId= must match an active session ID from a GET /sse connection.

npx is slow on first run

npx -y downloads the package on first invocation. After the npm cache is populated it starts instantly. Use a global install (npm install -g) for better cold-start performance.


Contributing

Contributions welcome! See CONTRIBUTING.md · CODE_OF_CONDUCT.md

License

MIT License · opensource.org/licenses/MIT


Documentation

| Document | Description | |----------|-------------| | Project README | Full project overview and complete documentation index | | Tools reference | All 14 MCP tools — parameters, returns, error cases, examples | | Architecture | stdio/SSE transports, auth flow, source walkthrough, CI/CD | | Python server | Python/FastMCP implementation | | VS Code extension | IDE extension setup | | Code Engine deploy | IBM Code Engine SSE deployment | | WxO deploy | watsonx Orchestrate deployment |


Topics & keywords

zendesk · zendesk-api · zendesk-mcp · zendesk-support · zendesk-tickets · mcp · mcp-server · model-context-protocol · cursor · claude · claude-desktop · github-copilot · vscode · ai-agent · ai-agents · tool-calling · function-calling · llm-tools · customer-support · customer-service · helpdesk · help-desk · service-desk · support-tickets · ticketing · crm · watsonx · watsonx-orchestrate · ibm-cloud · ibm-code-engine · typescript · fastmcp · stdio · sse · npx · automation · npm-package


Author: Markus van Kempen
Email: [email protected] · [email protected]
Website: markusvankempen.github.io
No bug too small, no syntax too weird.