Zendesk MCP Server (Extended)
This server is an extended, production-grade Model Context Protocol (MCP) server for Zendesk, enabling secure, multi-tenant interactions via AI applications. It provides comprehensive tools for ticket, user, group, knowledge base, and attachment management, deployable locally (stdio for Claude Desktop) or remotely (HTTP with TLS).
Read Operations (tickets:read scope):
get_ticket– retrieve a specific ticket by IDget_tickets– list tickets with cursor pagination and sort optionsget_ticket_comments– fetch paginated comments including attachment metadatasearch_tickets– search using Zendesk query syntaxget_ticket_attachment– download image attachments as base64get_user– resolve user ID to detailssearch_users– search users by name/emaillist_groups– list agent groups/teamslist_ticket_fields– list all ticket fields with IDs, types, and options
Knowledge Base (kb:read scope):
search_articles– search Help Center articles (also available as a resourcezendesk://knowledge-base)
Write Operations (tickets:write scope):
create_ticket– create a ticket with custom fields, tags, assignee, priority, etc.update_ticket– update status, priority, assignee, tags, due date, custom fieldscreate_ticket_comment– add public/internal comment with optional attachments (public comments may trigger human-in-the-loop confirmation)upload_attachment– upload a file (base64, ≤10 MB) and get a token for attaching to comments
Prompts: analyze-ticket and draft-ticket-response for assisted workflows.
Security & Access Control: OAuth 2.1 and scoped API keys (zmk_ prefix) with fine-grained permissions (tool-specific scopes: tickets:read, tickets:write, kb:read, *); tool-list filtering; optional human-in-the-loop confirmation for destructive actions; dual Zendesk identity (restricted user for reads, full agent for writes).
Multi-Tenancy: Route requests to different Zendesk accounts per API key or OAuth claim, with per-tenant credentials.
Deployment: Local stdio for Claude Desktop; remote Streamable HTTP with TLS, health checks; Docker, Docker Compose with Caddy, Terraform for AWS EC2/ECS Fargate with ALB.
Admin Console: Separate web interface for managing tenants, API keys, and Zendesk connection settings, plus a zendesk-keys CLI.
Additional Features: Cursor-based pagination to avoid context blowout; structured tool annotations; backward compatibility with the original reminia/zendesk-mcp-server.
Provides tools for managing Zendesk tickets (create, update, comment, search), users, groups, ticket fields, knowledge base articles, and attachments.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Zendesk MCP Server (Extended)show me open tickets about billing"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Zendesk MCP Server (Extended Edition)
A production-grade Model Context Protocol (MCP) server for Zendesk — run it locally with Claude Desktop over stdio, or deploy it to the cloud as a secure, multi-tenant, OAuth-protected remote MCP server that any AI application can connect to.
Note — extension of the original project
This is an extended fork of reminia/zendesk-mcp-server. The original provides a local, stdio-only Zendesk MCP server with basic ticket tools. This edition keeps full backward compatibility with it (stdio mode, original tools, prompts, and knowledge-base resource) and extends it for remote, internet-facing production use.
Issues with the original repo that this edition addresses
# | Issue in original | How it's addressed here |
1 | stdio transport only — could not be reached over a network, so it only worked on the same machine as the AI client | Streamable HTTP transport ( |
2 | No authentication of any kind — anyone who could reach the process could use it | Three auth modes: internal scoped API keys, OAuth 2.1 resource server (generic OIDC + RFC 9728 discovery), or both simultaneously |
3 | No permission model — every caller could read and write tickets | 4-layer read/write control: per-tool scopes (fail-closed), tool-list filtering, human-in-the-loop confirmation, dual Zendesk identity backstop |
4 | Blocking I/O inside async handlers — sync Zenpy calls froze the event loop under concurrent HTTP load | All Zendesk calls run in worker threads ( |
5 | Deprecated offset pagination — Zendesk is sunsetting it; comments were not paginated at all (context blowout on long tickets) | Cursor pagination ( |
6 | Sparse Zendesk coverage — only 5 tools; user/assignee IDs could not be resolved, custom fields were opaque, no search | 14 tools including search, users, groups, ticket-field metadata, KB article search, attachment upload |
7 | Single Zendesk account hard-wired at startup from | Multi-tenancy: per-tenant Zendesk credentials, keys/OAuth claims mapped to tenants, hot-swappable connection settings |
8 | No deployment story — no TLS, no health check, stdio-oriented Docker image | Docker (HTTP-first, healthcheck), docker-compose with Caddy auto-TLS, Terraform for EC2 and for ECS Fargate + ALB |
9 | No admin tooling — key rotation/credential changes required editing | Web admin console (separate port) + |
10 | No tests | 38 unit tests + HTTP/admin/OAuth smoke test suites; tests run in CI |
Related MCP server: tokenless-zendesk-mcp
Feature overview
Original features (retained):
Ticket tools: get ticket, list tickets, get comments, create ticket, update ticket, comment on ticket
Image attachment download with security hardening (MIME allowlist, magic-byte validation, 10 MB cap)
Prompts:
analyze-ticket,draft-ticket-responseResource:
zendesk://knowledge-base(all Help Center articles, cached 1 h)stdio transport for Claude Desktop / Claude Code local use
New in this edition:
Streamable HTTP transport with
/healthendpointInternal API keys:
zmk_prefix, SHA-256 hashed at rest, scopes, expiry, instant revocation, audit logOAuth 2.1 resource server: JWKS/issuer/audience JWT validation, RFC 9728 Protected Resource Metadata at
/.well-known/oauth-protected-resource/mcp— works with Auth0, Descope, Cognito, Keycloak, WorkOSScope model:
tickets:read,tickets:write,kb:read,*— enforced per tool, fail-closed, with tools/list filteringOptional elicitation: in-client approve/decline before posting public (customer-visible) comments
Dual Zendesk identity: reads via a restricted user (e.g. light agent), writes via a full agent
Multi-tenancy with per-tenant Zendesk credentials
Web admin console: connection settings (hot-swap + test), tenant management, key lifecycle
New tools:
search_tickets,get_user,search_users,list_groups,list_ticket_fields,search_articles,upload_attachmentTool annotations (
readOnlyHint/destructiveHint) and structured output on all toolsDeployment: Dockerfile, docker-compose + Caddy (auto-TLS), Terraform for EC2 and ECS Fargate
MCP Registry manifest (
server.json) and publishing guide
Tools
Tool | Scope | Description |
| tickets:read | Get a ticket by ID |
| tickets:read | List tickets (cursor pagination, sortable) |
| tickets:read | Ticket comments incl. attachment metadata (cursor pagination) |
| tickets:read | Zendesk search syntax, e.g. |
| tickets:read | Download an image attachment (base64, validated) |
| tickets:read | Resolve a user ID to name/email/role |
| tickets:read | Search users by name or email |
| tickets:read | Agent groups (teams) for routing |
| tickets:read | Field metadata — interpret/set |
| kb:read | Search Help Center articles (context-safe) |
| tickets:write | Create a ticket |
| tickets:write | Update status/priority/assignee/tags/custom fields/due date |
| tickets:write | Comment on a ticket (optional elicitation for public comments; supports attachments) |
| tickets:write | Upload a file (≤10 MB), returns token for comment attachment |
Prompts: analyze-ticket, draft-ticket-response. Resource: zendesk://knowledge-base (kb:read).
Quick start (local, stdio — same as the original)
git clone <this-repo>
cd zendesk-mcp-server
uv venv && uv pip install -e .
cp .env.example .env # fill in ZENDESK_SUBDOMAIN, ZENDESK_EMAIL, ZENDESK_API_KEYClaude Desktop config:
{
"mcpServers": {
"zendesk": {
"command": "uv",
"args": ["--directory", "/path/to/zendesk-mcp-server", "run", "zendesk"]
}
}
}stdio mode is trusted-local: no auth, full access, identical behavior to the original repo.
Remote mode (Streamable HTTP)
MCP_TRANSPORT=http zendesk # serves http://0.0.0.0:8000/mcp + /healthCreate scoped API keys (shown once, stored hashed):
zendesk-keys create --name "reader" --scopes tickets:read,kb:read
zendesk-keys create --name "agent" --scopes tickets:read,tickets:write,kb:read --expires-days 30
zendesk-keys create --name "admin" --scopes "*"
zendesk-keys list
zendesk-keys revoke --id 2Connect a client:
claude mcp add zendesk --transport http https://mcp.example.com/mcp \
--header "Authorization: Bearer zmk_..."Read-only keys never see write tools in tools/list; write calls without
tickets:write are denied; unknown tools are denied by default (fail closed).
Configuration reference
All configuration is via environment variables (or .env; the admin console can
override connection settings at runtime, persisted in the key-store DB).
Zendesk connection
Variable | Required | Default | Description |
| yes | — |
|
| yes | — | Zendesk API token |
| yes* | — | Single-identity mode: agent email paired with the token |
| no |
| Dual identity: restricted user (light agent) for all reads |
| no |
| Dual identity: full agent for all writes |
*Either ZENDESK_EMAIL or both ZENDESK_READ_EMAIL/ZENDESK_WRITE_EMAIL.
Zendesk roles live on the user, not the token — pairing the same token with a
restricted user email yields restricted permissions (Layer 4 backstop).
Transport
Variable | Default | Description |
|
|
|
|
| HTTP bind address |
|
| HTTP port; MCP endpoint is |
Authentication
Variable | Default | Description |
|
| Set |
|
|
|
|
| SQLite store for keys, tenants, config, audit log |
| — | Public base URL (required for oauth/both; used in RFC 9728 metadata) |
| — | OIDC issuer, e.g. |
|
| Audience/identifier of this server at the IdP |
|
| Override if your IdP differs |
| issuer | Comma-separated authorization server URLs |
|
| JWT claim naming the caller's tenant (id or name) |
Admin console & safety
Variable | Default | Description |
| — (disabled) | Setting it enables the admin console |
|
| Keep loopback; reach via SSH/SSM tunnel |
|
| Admin console port (never expose publicly) |
|
| Elicit user approval before PUBLIC comments (Layer 3) |
Security model
Layer | Mechanism |
Edge | TLS 1.2+ (Caddy or ALB/ACM), security headers, 80/443 only |
AuthN | API keys (hashed, expiring, revocable) and/or OAuth 2.1 JWTs (PKCE at the IdP) |
L1 AuthZ | Central |
L2 Visibility |
|
L3 Confirmation |
|
L4 Zendesk | Dual identity — reads through a restricted Zendesk user, writes through a full agent |
Admin | Separate loopback port, password + CSRF, secrets never re-displayed |
Audit | Append-only log: key lifecycle, admin actions, logins, writes |
Multi-tenancy
By default every caller uses the server's own Zendesk connection. To let other teams/customers connect their Zendesk:
Admin console → Tenants → add name, subdomain, API token, read/write emails.
Bind credentials to the tenant: create an API key with that tenant selected (or
zendesk-keys create ... --tenant-id N), or configure your IdP to issue the tenant's name/id in theMCP_OAUTH_TENANT_CLAIMJWT claim.All tool calls from that identity are routed to the tenant's Zendesk. Deleting a tenant revokes its keys immediately.
Web admin console
Enable with MCP_ADMIN_PASSWORD. Reach it via tunnel — never expose it:
ssh -L 9000:localhost:9000 user@host # or the SSM equivalent, see docs/DEPLOYMENT.md
# open http://localhost:9000Provides: Zendesk connection editor with hot-swap (no restart) and "test connection", tenant management, API key create/revoke with scope checkboxes and expiry, and key usage visibility. Stored tokens are never re-displayed; new keys are shown exactly once.
Deployment
Docker (single container):
docker build -t zendesk-mcp-server .
docker run --rm -p 8000:8000 --env-file .env -v zmcp-keys:/data zendesk-mcp-serverDocker Compose + automatic TLS (recommended single-box): set MCP_DOMAIN in
.env, then docker compose up -d — Caddy terminates TLS with Let's Encrypt and
proxies to the server. Create keys with
docker compose exec zendesk-mcp zendesk-keys create ....
AWS EC2 (Terraform): terraform/ provisions EC2 (SSM access, no SSH, IMDSv2),
security group (80/443 only), Elastic IP, optional Route53, and bootstraps
Docker + the repo. Full runbook: docs/DEPLOYMENT.md.
Windows Server without Docker: native Python + Caddy with your own TLS certificate + NSSM services, including a troubleshooting FAQ of real-world Windows issues (Node/PATH, cert chains, arg mangling): docs/WINDOWS_SETUP.md.
AWS ECS Fargate + ALB (scale-out): terraform/ecs/ provisions ECR, Fargate
service, ALB with ACM/TLS 1.3, EFS-backed key store, Secrets Manager injection,
and CloudWatch. Keep desired_count=1 until the key store is migrated off SQLite.
MCP Registry: fill in server.json and follow docs/REGISTRY.md
to publish your deployed server to registry.modelcontextprotocol.io.
Development
uv sync --extra dev
uv run pytest tests/ -v # 38 tests: tools, keystore, permissions, tenancy, auth modesProject layout:
src/zendesk_mcp_server/
server.py # FastMCP app: tools, prompts, resources, transports
zendesk_client.py # Zendesk API client (dual identity, cursor pagination)
auth.py # API-key verifier, OIDC JWT verifier, auth-mode factory
permissions.py # Scope model + enforcement/filtering middleware
keystore.py # SQLite: keys, tenants, audit log
runtime.py # Client holder: hot-swap + per-tenant routing
admin.py # Web admin console (separate port)
keys_cli.py # zendesk-keys CLI
config.py # Env-based settings
terraform/ # EC2 deployment terraform/ecs/ # Fargate deployment
docs/ # Architecture plan, deployment runbook, registry guideArchitecture decisions and full history: docs/REMOTE_MCP_ARCHITECTURE_PLAN.md.
License
Apache 2.0 — same as the original project. Original work by reminia; extensions as described above.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseDqualityDmaintenanceA comprehensive MCP server for managing Zendesk Support, Talk, Chat, and Guide products, providing tools for tickets, users, organizations, search, and more.Last updated4928
- AlicenseAqualityBmaintenanceMCP server that authenticates via browser session cookies to access Zendesk's REST API without API tokens, supporting reads and writes with agent permissions.Last updated1931MIT
- AlicenseAqualityDmaintenanceA Model Context Protocol server that enables AI assistants like Claude to interact with Zendesk Support through natural language for searching, creating, updating, and managing tickets.Last updated413913MIT
- Alicense-qualityBmaintenanceMCP server for Zendesk support workflows that enables ticket search, lookup, creation, commenting, status updates, and user listing through natural language. It uses OAuth authentication and supports both internal notes and public comments.Last updatedMIT
Related MCP Connectors
Zendesk MCP Pack — tickets, users, organizations via OAuth.
A MCP server built for developers enabling Git based project management with project and personal…
An MCP server that let you interact with Cycloid.io Internal Development Portal and Platform
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/srinivas-86/zendesk-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server