🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@markusvankempen/zendesk-mcp-server

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@markusvankempen/zendesk-mcp-server

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

latest
Source
npmnpm
Version
1.0.2
Version published
Weekly downloads
105
50%
Maintainers
1
Weekly downloads
 
Created
Source

@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: markus.van.kempen@gmail.com · mvk@ca.ibm.com
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

VariableRequiredDefaultDescription
ZENDESK_SUBDOMAINYesYour Zendesk tenant prefix. mycompanymycompany.zendesk.com
ZENDESK_EMAILYesService account email used for API authentication
ZENDESK_API_TOKENYesZendesk API token (Settings → Channels → API)
MCP_TRANSPORTNostdioSet to sse to start an HTTP server instead of stdio
PORTNo8080HTTP port for SSE mode
HOSTNo0.0.0.0HTTP bind address for SSE mode

Getting a Zendesk API token:

  • Log in to your Zendesk Admin UI
  • Go to Admin → Apps and Integrations → APIs → Zendesk API
  • Enable Token Access
  • Click "Add API token"
  • 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": "bot@mycompany.com",
        "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 alice@example.com 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": "bot@mycompany.com",
        "ZENDESK_API_TOKEN": "xxxxxxxxxxxxxxxxxxxx"
      }
    }
  }
}

Restart Claude Desktop after saving.

Quick start — VS Code

Using the VS Code extension (recommended):

  • Install zendesk-mcp-vscode from VS Marketplace or Open VSX
  • Run command Zendesk MCP: Configure Credentials
  • Enter subdomain, email, and API token
  • 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": "bot@mycompany.com",
        "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.

ToolWhat it does
create_ticketCreate ticket with correct customer requester attribution
get_ticketGet full ticket details by ID
update_ticketChange status, priority, tags, or add a comment
search_ticketsSearch with Zendesk query syntax
list_recent_ticketsMost recently updated tickets
list_all_ticketsAdmin-wide listing with optional status filter
list_tickets_for_requesterAll tickets owned by a specific customer email
get_ticket_commentsFull conversation history (public + internal)
add_ticket_commentPost a reply or internal note
get_user_by_emailLook up a Zendesk user record
close_ticketMark a ticket as solved
reopen_ticketReopen a solved/closed ticket
get_ticket_metricsSLA and timing metrics
assign_ticketAssign 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 \
ZENDESK_EMAIL=bot@mycompany.com \
ZENDESK_API_TOKEN=xxxx \
MCP_TRANSPORT=sse \
PORT=8080 \
zendesk-mcp-server

SSE endpoints

PathMethodDescription
GET /sseGETOpens a persistent SSE stream. Response stays open. Server sends event: endpoint with data: /message?sessionId=<uuid>.
POST /message?sessionId=<id>POSTSend a JSON-RPC request. Response arrives via the SSE stream.
GET /healthGETReturns 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 ZENDESK_EMAIL=a@b.com 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:

  • Accepting requester_email as a required parameter in create_ticket
  • Looking up the customer in Zendesk by email
  • Creating the customer as a Zendesk user if they don't exist (with verified: true)
  • 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 ZENDESK_EMAIL=a@b.com 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

DocumentDescription
Project READMEFull project overview and complete documentation index
Tools referenceAll 14 MCP tools — parameters, returns, error cases, examples
Architecturestdio/SSE transports, auth flow, source walkthrough, CI/CD
Python serverPython/FastMCP implementation
VS Code extensionIDE extension setup
Code Engine deployIBM Code Engine SSE deployment
WxO deploywatsonx 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: markus.van.kempen@gmail.com · mvk@ca.ibm.com
Website: markusvankempen.github.io
No bug too small, no syntax too weird.

Keywords

mcp

FAQs

Package last updated on 10 Jun 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts