About
Zendesk MCP server on Cloudflare
README
This is a Model Context Protocol (MCP) server that provides comprehensive Zendesk API integration with Google OAuth authentication, deployed on Cloudflare Workers.
The server allows MCP clients (like Claude Desktop) to interact securely with Zendesk APIs through authenticated remote connections. It reads across tickets, users, organizations, the Help Center and more, and writes only macros.
Features
Zendesk API Coverage
The server reads widely and writes only macros. Reading covers:
- Tickets: List, fetch and search support tickets
- Users: List, fetch and search users
- Organizations: List, fetch and search organizations
- Groups: List and fetch agent groups
- Macros: List and fetch ticket macros
- Views: List and fetch ticket views
- Triggers: List and fetch triggers
- Automations: List and fetch automations
- Search: Search across all Zendesk data
- Help Center: Browse and search the knowledge base — articles, sections and categories
- Support: General configuration information
- Talk: Access call center statistics
- Chat: Read chat conversations
Writing is limited to creating and updating macros. Available Tools explains why, and what happens if you ask for anything else.
Technical Features
- Google OAuth Authentication: Secure user authentication flow
- Remote MCP Protocol: Streamable HTTP, stateless — each request stands alone, with no session to establish or keep alive
- Cloudflare Workers: Serverless deployment with global edge distribution
- Type Safety: Full TypeScript implementation with Zod validation
- Error Handling: Comprehensive error handling with user-friendly messages
- Modular Architecture: Easy to extend with additional tools
Getting Started
Prerequisites
- Zendesk instance with API access
- Google Cloud Platform account for OAuth
- Cloudflare account for deployment
- pnpm, which this project uses as its package manager. The exact version is pinned in
package.json, and recent versions of pnpm will switch to it for you.
1. Zendesk Setup
- In your Zendesk Admin Center, go to Apps and integrations > APIs > Zendesk API
- Enable token access and generate an API token
- Note your Zendesk subdomain (e.g.,
companyfromcompany.zendesk.com)
2. Google OAuth Setup
For Production
Create a Google Cloud OAuth App:
- Homepage URL:
https://zendesk-mcp.<your-subdomain>.workers.dev - Authorization callback URL:
https://zendesk-mcp.<your-subdomain>.workers.dev/callback - Note your Client ID and generate a Client secret
If you put the worker behind a custom domain, register that hostname here too. The worker builds its callback from whichever host the request arrived on, so connecting through https://zendesk.example.com/mcp sends Google a redirect URI of https://zendesk.example.com/callback. Registering only the workers.dev hostname is easy to misdiagnose, because every endpoint on the worker keeps answering normally and the flow fails at the Google consent screen with redirect_uri_mismatch.
For Local Development
Create a separate OAuth App for development:
- Homepage URL:
http://localhost:8788 - Authorization callback URL:
http://localhost:8788/callback
3. Environment Setup
Set production secrets via Wrangler:
pnpm exec wrangler secret put GOOGLE_CLIENT_ID
pnpm exec wrangler secret put GOOGLE_CLIENT_SECRET
pnpm exec wrangler secret put COOKIE_ENCRYPTION_KEY # Random string, e.g. openssl rand -hex 32
pnpm exec wrangler secret put ZENDESK_SUBDOMAIN
pnpm exec wrangler secret put ZENDESK_EMAIL
pnpm exec wrangler secret put ZENDESK_API_TOKEN
pnpm exec wrangler secret put HOSTED_DOMAIN # Optional: restrict to specific Google domain
For local development, create .dev.vars:
GOOGLE_CLIENT_ID=your_dev_client_id
GOOGLE_CLIENT_SECRET=your_dev_client_secret
ZENDESK_SUBDOMAIN=your_subdomain
[email protected]
ZENDESK_API_TOKEN=your_api_token
4. KV Namespace Setup
pnpm exec wrangler kv namespace create "OAUTH_KV"
# Update wrangler.jsonc with the returned KV ID
5. Deploy & Test
Deploy to Production
pnpm install
pnpm run deploy
Local Development
pnpm install
pnpm run dev
Test with MCP Inspector
pnpm dlx @modelcontextprotocol/inspector
The cooldown in pnpm-workspace.yaml applies here too, so this resolves to the newest inspector released more than a week ago rather than the absolute newest.
- For production: Enter
https://zendesk-mcp.<your-subdomain>.workers.dev/mcp - For local: Enter
http://localhost:8788/mcp
Complete the authentication flow and you'll see the tools the server publishes.
Connecting a Claude Client
There are two routes in, and they behave differently enough that the choice matters. Prefer the connector unless something rules it out.
As a custom connector
Claude holds remote MCP servers on your account rather than in a file on disk, so there is nothing to install and no Node runtime on the machine. Each person adds it once themselves, and it asks for a display name as well as the URL:
Name Momentum Zendesk
URL https://zendesk-mcp.<your-subdomain>.workers.dev/mcp
Inside Claude Desktop that is Settings → Connectors → Add custom connector, which Cmd+, opens directly. At claude.ai it sits under Customize → Connectors instead, behind the + button.
An Owner on Team or Enterprise can instead enable the connector for the whole organization, under Organization settings → Connectors. That saves everyone adding it, but it does not sign anyone in — each member still authorizes individually the first time they use it, unless the organization has configured managed authentication.
Either way the connector follows the account rather than the machine, so it appears in Claude Desktop and at claude.ai both, and claude_desktop_config.json is not involved at all.
/mcp is the only endpoint. /sse served the superseded HTTP+SSE transport, which MCP revision 2026-07-28 deprecates outright, and it has been removed — a client configured against it now gets nothing. Clients too old to speak the current revision are still served at /mcp, so on transport grounds this only strands one that can speak HTTP+SSE and nothing else.
One other kind of client is turned away, for an unrelated reason. The server validates the Origin header whenever a request carries one. By default it accepts localhost, and also the worker's own hostname when you are on a workers.dev address — so a page served from the worker itself is fine, while a custom domain is left allowing localhost alone. Any other origin gets a 403. Nothing described on this page is affected, since a connector is fetched by Anthropic's servers and mcp-remote runs under Node, and neither sends an Origin at all. It is simply the first thing to check if a browser-based client fails with a message about origins rather than about transports.
Anthropic's infrastructure makes this connection rather than the user's machine, so the worker has to be reachable over the public internet, which a deployed worker already is. That is also the property that makes this route viable for people who will never open a terminal: nothing runs locally, so there is nothing local to go wrong. HOSTED_DOMAIN still governs who may sign in, so a connector does not widen access.
Through the mcp-remote proxy
Servers listed in claude_desktop_config.json are started as local programs and spoken to over stdin and stdout, so reaching an HTTP server needs a local adapter in between. Use this only for clients that cannot take a connector.
Open the file with Settings → Developer → Edit Config, or edit it directly:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json, which expands toC:\Users\<you>\AppData\Roaming\Claude\claude_desktop_config.json
The file usually already holds your app preferences, so add mcpServers alongside the keys that are there rather than replacing the whole thing. Leave the command as npx and not pnpm dlx: it runs on the user's own machine, where Node ships npx but pnpm may not be installed at all. The -y matters, because npx asks to confirm before installing a package it does not have yet and there is no terminal for anyone to answer in.
{
"mcpServers": {
"zendesk": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://zendesk-mcp.<your-subdomain>.workers.dev/mcp",
"--auth-timeout",
"120"
]
}
}
}
Claude Desktop reads this file only at launch, so quit it fully and start it again — closing the window leaves it running in the background and changes nothing. On macOS press Cmd+Q, and on Windows right-click the tray icon and choose Quit. To point at a local server instead, run pnpm run dev and use http://localhost:8788/mcp.
This route asks a lot more of the machine, and the failures are worth knowing before handing it to anyone:
- Node has to be installed.
npxis not present on a machine without Node, which rules this out for most non-technical users on its own. - Two timers run against first-time sign-in, and both are short.
mcp-remotewaits 30 seconds for the OAuth callback unless--auth-timeoutsays otherwise, and Claude Desktop separately cancels a server that has not finished initializing within 60 seconds. Picking a Google account can outlast either. The symptom is a browser landing onlocalhost:<port>with nothing listening, because the proxy was gone before the redirect came back. Retrying usually works, since the second attempt reuses the approval cookie and the Google session — which is exactly why this is easy to dismiss as a fluke. - A slow tool call gets dropped. Node's fetch abandons a response body after 300 seconds of silence, which surfaces as
Body Timeout Errorand a reconnect underneath you — and reconnecting can re-enter the auth path and open a browser window unprompted. This used to be the common failure, because the server held a stream open between calls for the old transport to push down. It no longer holds one, so the only way to sit silent that long now is a single Zendesk request taking five minutes. - Windows cannot find
npx. Claude Desktop spawns the command without a shell, so the.cmdshim never resolves. Use"command": "cmd"with"args": ["/c", "npx", "mcp-remote", "<your-url>"]. - Tokens are cached on disk. They live in
~/.mcp-authon macOS and%USERPROFILE%\.mcp-authon Windows. Delete that folder if authentication gets stuck after a URL change. A stale lockfile there needs no attention, since the proxy detects and clears it.
Either way
Authenticate through the browser flow when prompted, then ask Claude to:
- "Show me the latest support tickets"
- "Search for tickets about billing problems"
- "List all users in the Sales organization"
- "Draft a macro that solves a ticket and thanks the customer"
Available Tools
The server reads widely and writes almost nothing.
Reading covers tickets, users, organizations, groups, macros, views, triggers, automations, Talk statistics, Chat conversations and the whole Help Center — listing them, fetching one by ID, and searching. Anything named list_*, get_* or search_* is available, along with search and support_info.
Writing is limited to create_macro and update_macro. A macro is a shortcut an agent applies to a ticket by hand, so creating one changes nothing on its own — which is why these two are permitted where nothing else is.
Everything else is refused. Creating, updating and deleting a ticket, and creating a user, an organization or a group, are all written and working in the code but never offered to a client, so asking for them will not work. Nothing else writes at all — deleting a macro, for instance, was never built as a tool. The server logs what it withheld each time it starts.
The permitted set is decided in src/utils/tool-registry.ts, and the tools themselves are defined under src/tools/. See CLAUDE.md for how a tool gets permitted.
Development
Adding New Tools
To extend with additional Zendesk tools:
- Add API methods to
ZendeskClientinsrc/zendesk-client.ts - Create tool definitions in appropriate
src/tools/file - Export tools from
src/tools/index.ts
Example:
// In src/tools/custom.ts
export const customTools: ToolDefinition[] = [
createTool(
'my_custom_tool',
'Description of what this tool does',
{ param: z.string().describe('Parameter description') },
async (client: ZendeskClient, { param }) => {
return client.myCustomMethod(param)
}
),
]
Project Structure
src/
├── index.ts # Main entry point
├── google-handler.ts # OAuth handler
├── zendesk-client.ts # Zendesk API client
├── tools/ # MCP tool definitions
├── types/ # TypeScript types
└── utils/ # Utilities and helpers
Architecture
This server demonstrates a clean architecture for remote MCP servers:
- OAuth Provider: Handles secure authentication with Google
- API Client: Cloudflare Workers-compatible HTTP client
- Tool Registry: Modular tool organization and registration
- Error Handling: Functional approach with consistent error responses
- Type Safety: Full TypeScript with runtime validation
This pattern can be adapted for other APIs by:
- Replacing
ZendeskClientwith your API client - Creating new tool definitions in
src/tools/ - Updating environment variables and configuration
Support
For issues and questions:
- Check the MCP documentation
- Review Cloudflare Workers docs
- Consult Zendesk API documentation
Installing Zendesk Mcp Cloudflare
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/levibe/zendesk-mcp-cloudflareFAQ
Is Zendesk Mcp Cloudflare MCP free?
Yes, Zendesk Mcp Cloudflare MCP is free — one-click install via Unyly at no cost.
Does Zendesk Mcp Cloudflare need an API key?
No, Zendesk Mcp Cloudflare runs without API keys or environment variables.
Is Zendesk Mcp Cloudflare hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Zendesk Mcp Cloudflare in Claude Desktop, Claude Code or Cursor?
Open Zendesk Mcp Cloudflare on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
GitHub
PRs, issues, code search, CI status
by GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
by mcpdotdirectCompare Zendesk Mcp Cloudflare with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All development MCPs
