@fruggr/zendesk-mcp-server 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +341 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2092 -0
- package/dist/index.js.map +1 -0
- package/package.json +88 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Digital4Better
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
# Zendesk MCP Server
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@fruggr/zendesk-mcp-server)
|
|
4
|
+
|
|
5
|
+
A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that connects LLMs to the **Zendesk Support & Help Center APIs** — with per-user OAuth 2.1 PKCE authentication and fine-grained tool visibility controls.
|
|
6
|
+
|
|
7
|
+
## Why this server?
|
|
8
|
+
|
|
9
|
+
Most Zendesk integrations use a shared admin API key, giving every user full access to every ticket. This server takes a different approach:
|
|
10
|
+
|
|
11
|
+
- **Per-user authentication** — Each user authenticates with their own Zendesk credentials via OAuth 2.1 PKCE. No shared admin key, no elevated privileges. The LLM sees exactly what the user is allowed to see.
|
|
12
|
+
- **Context-friendly tool modes** — Expose 36 individual tools, 3 namespace proxies, or a single unified tool. Choose the mode that fits your LLM's context budget.
|
|
13
|
+
- **Section-based article editing** — For large Help Center articles, read and rewrite one section at a time (parsed by h1/h2/h3 headings) instead of shuffling the full HTML body through the LLM. Reduces tokens by 10–100× on targeted edits.
|
|
14
|
+
- **Read-only mode** — Restrict the server to read operations only, ideal for assistants that should never modify data.
|
|
15
|
+
- **Zero runtime dependencies beyond the MCP SDK** — Built on `@modelcontextprotocol/sdk` and `zod`. No Express, no heavyweight frameworks.
|
|
16
|
+
|
|
17
|
+
> Built and maintained by [Digital4better](https://digital4better.com) for the [Fruggr](https://www.fruggr.io) project.
|
|
18
|
+
|
|
19
|
+
## Tool modes
|
|
20
|
+
|
|
21
|
+
The server registers tools in one of three modes, controlled by `--mode`:
|
|
22
|
+
|
|
23
|
+
| Mode | Tools exposed | Best for |
|
|
24
|
+
|------|--------------|----------|
|
|
25
|
+
| **`all`** | 36 individual tools (`get_ticket`, `search_articles`, ...) | Clients with good tool selection, full granularity |
|
|
26
|
+
| **`namespace`** (default) | 3 proxy tools (`zendesk_tickets`, `zendesk_help_center`, `zendesk_users`) | Balanced context usage, grouped operations |
|
|
27
|
+
| **`single`** | 1 proxy tool (`zendesk`) | Minimal context footprint, single entry point |
|
|
28
|
+
|
|
29
|
+
In `namespace` and `single` modes, the proxy tool accepts `{ "operation": "<tool_name>", "params": { ... } }` and dispatches to the appropriate handler after validating params through the original Zod schema. Proxy descriptions include only the first sentence of each sub-operation to stay compact; the full schema is applied when the operation is actually called.
|
|
30
|
+
|
|
31
|
+
> **Tip:** The `single` mode is particularly useful for models with limited tool slots — one tool handles all 36 operations.
|
|
32
|
+
|
|
33
|
+
### Scoping the surface
|
|
34
|
+
|
|
35
|
+
`--namespace` and `--read-only` apply to every mode (including the default `namespace` mode) — they filter tools **before** the proxies are built, so the description of each proxy reflects only the operations that survive the filters. Combine them to register a focused surface:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Only the Help Center proxy, only read-only operations
|
|
39
|
+
zendesk-mcp-server acme --namespace help_center --read-only
|
|
40
|
+
|
|
41
|
+
# Only the Tickets proxy (read + write)
|
|
42
|
+
zendesk-mcp-server acme --namespace tickets
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`--namespace` is repeatable. `--tool` is also available for cherry-picking individual operations but forces `--mode all`.
|
|
46
|
+
|
|
47
|
+
## Available tools
|
|
48
|
+
|
|
49
|
+
<details>
|
|
50
|
+
<summary><strong>Tickets</strong> (9 tools)</summary>
|
|
51
|
+
|
|
52
|
+
| Tool | Description | Mode |
|
|
53
|
+
|------|-------------|------|
|
|
54
|
+
| `get_ticket` | Retrieve a ticket by ID with optional comments | read |
|
|
55
|
+
| `search_tickets` | Search tickets using Zendesk query syntax | read |
|
|
56
|
+
| `list_tickets` | List tickets with cursor-based pagination | read |
|
|
57
|
+
| `get_linked_incidents` | Get incidents linked to a problem ticket | read |
|
|
58
|
+
| `create_ticket` | Create a new ticket with subject, description, priority, tags... | write |
|
|
59
|
+
| `update_ticket` | Update ticket status, priority, assignee, tags, custom fields | write |
|
|
60
|
+
| `add_private_note` | Add an internal note (not visible to requester) | write |
|
|
61
|
+
| `add_public_comment` | Add a public comment (visible to requester) | write |
|
|
62
|
+
| `manage_tags` | Add or remove tags on a ticket | write |
|
|
63
|
+
|
|
64
|
+
</details>
|
|
65
|
+
|
|
66
|
+
<details>
|
|
67
|
+
<summary><strong>Help Center</strong> (21 tools)</summary>
|
|
68
|
+
|
|
69
|
+
| Tool | Description | Mode |
|
|
70
|
+
|------|-------------|------|
|
|
71
|
+
| `search_articles` | Full-text search across Help Center articles | read |
|
|
72
|
+
| `get_article` | Retrieve article by ID with full HTML body | read |
|
|
73
|
+
| `get_article_outline` | Compact outline of an article (sections + available translations) | read |
|
|
74
|
+
| `get_article_section` | Retrieve a single section (html or markdown) | read |
|
|
75
|
+
| `list_categories` | List all Help Center categories | read |
|
|
76
|
+
| `list_sections` | List sections, optionally filtered by category | read |
|
|
77
|
+
| `list_articles` | List articles with sorting and translation info | read |
|
|
78
|
+
| `list_article_translations` | List available translations for an article | read |
|
|
79
|
+
| `list_article_attachments` | List attachments on an article | read |
|
|
80
|
+
| `list_permission_groups` | List Guide permission groups (needed to create articles) | read |
|
|
81
|
+
| `list_content_tags` | List Guide content tags (end-user visible) | read |
|
|
82
|
+
| `list_labels` | List article labels (search ranking, not user-visible) | read |
|
|
83
|
+
| `list_user_segments` | List user segments (article visibility) | read |
|
|
84
|
+
| `compare_translations` | Section-level diff between two locales of an article | read |
|
|
85
|
+
| `create_article` | Create a new article in a section | write |
|
|
86
|
+
| `update_article` | Update article metadata (draft, labels, tags, visibility, section) | write |
|
|
87
|
+
| `create_article_translation` | Create a translation for an article | write |
|
|
88
|
+
| `update_article_translation` | Update an article's translation (full body) | write |
|
|
89
|
+
| `update_article_section` | Replace a single section of an article | write |
|
|
90
|
+
| `create_content_tag` | Create a new Guide content tag | write |
|
|
91
|
+
| `create_article_attachment` | Upload an attachment to an article | write |
|
|
92
|
+
|
|
93
|
+
</details>
|
|
94
|
+
|
|
95
|
+
<details>
|
|
96
|
+
<summary><strong>Users & Organizations</strong> (5 tools)</summary>
|
|
97
|
+
|
|
98
|
+
| Tool | Description | Mode |
|
|
99
|
+
|------|-------------|------|
|
|
100
|
+
| `get_current_user` | Get the authenticated user (verify identity) | read |
|
|
101
|
+
| `search_users` | Search users by name, email, or query syntax | read |
|
|
102
|
+
| `get_user` | Retrieve a user by ID | read |
|
|
103
|
+
| `get_organization` | Retrieve an organization by ID | read |
|
|
104
|
+
| `list_organizations` | List all organizations with pagination | read |
|
|
105
|
+
|
|
106
|
+
</details>
|
|
107
|
+
|
|
108
|
+
<details>
|
|
109
|
+
<summary><strong>Search</strong> (1 tool)</summary>
|
|
110
|
+
|
|
111
|
+
| Tool | Description | Mode |
|
|
112
|
+
|------|-------------|------|
|
|
113
|
+
| `search` | Unified search across tickets, users, and organizations | read |
|
|
114
|
+
|
|
115
|
+
</details>
|
|
116
|
+
|
|
117
|
+
## Prerequisites
|
|
118
|
+
|
|
119
|
+
- **Node.js** >= 20
|
|
120
|
+
- A **Zendesk** instance (Support or Suite)
|
|
121
|
+
|
|
122
|
+
## Installation
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Run without installing
|
|
126
|
+
npx -y @fruggr/zendesk-mcp-server <your-subdomain>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Or install globally:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
npm install -g @fruggr/zendesk-mcp-server
|
|
133
|
+
zendesk-mcp-server <your-subdomain>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Or clone and run locally:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
git clone https://github.com/fruggr/zendesk-mcp-server.git
|
|
140
|
+
cd zendesk-mcp-server
|
|
141
|
+
pnpm install
|
|
142
|
+
pnpm build
|
|
143
|
+
node dist/index.js <your-subdomain>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Authentication
|
|
147
|
+
|
|
148
|
+
The server supports two authentication methods:
|
|
149
|
+
|
|
150
|
+
### Option A: OAuth 2.1 PKCE (recommended)
|
|
151
|
+
|
|
152
|
+
No API key needed. Each user authenticates via their browser on the first tool call.
|
|
153
|
+
|
|
154
|
+
**Zendesk setup:**
|
|
155
|
+
|
|
156
|
+
1. Go to **Admin Center > Apps and integrations > APIs > OAuth Clients**
|
|
157
|
+
2. Create a public client:
|
|
158
|
+
- **Identifier**: `<your-subdomain>_zendesk` (or set `ZENDESK_OAUTH_CLIENT_ID`)
|
|
159
|
+
- **Redirect URL**: `http://localhost:3000/callback`
|
|
160
|
+
|
|
161
|
+
**Run:**
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
zendesk-mcp-server <your-subdomain>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
On the first tool call, a browser window opens for the user to authenticate. The token is cached in memory for the session.
|
|
168
|
+
|
|
169
|
+
### Option B: API token
|
|
170
|
+
|
|
171
|
+
For headless/CI environments or quick testing.
|
|
172
|
+
|
|
173
|
+
**Zendesk setup:**
|
|
174
|
+
|
|
175
|
+
1. Go to **Admin Center > Apps and integrations > APIs > Zendesk API**
|
|
176
|
+
2. Enable **Token Access**, create a token
|
|
177
|
+
|
|
178
|
+
**Run:**
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
ZENDESK_EMAIL=you@example.com ZENDESK_API_TOKEN=dneib123... \
|
|
182
|
+
zendesk-mcp-server <your-subdomain>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Configuration
|
|
186
|
+
|
|
187
|
+
### MCP client configuration
|
|
188
|
+
|
|
189
|
+
<details>
|
|
190
|
+
<summary><strong>Claude Desktop</strong></summary>
|
|
191
|
+
|
|
192
|
+
Add to your `claude_desktop_config.json`:
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
{
|
|
196
|
+
"mcpServers": {
|
|
197
|
+
"zendesk": {
|
|
198
|
+
"command": "npx",
|
|
199
|
+
"args": ["-y", "@fruggr/zendesk-mcp-server", "<your-subdomain>", "--mode", "single"],
|
|
200
|
+
"env": {
|
|
201
|
+
"ZENDESK_EMAIL": "you@example.com",
|
|
202
|
+
"ZENDESK_API_TOKEN": "your-api-token"
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
</details>
|
|
210
|
+
|
|
211
|
+
<details>
|
|
212
|
+
<summary><strong>Claude Code</strong></summary>
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
claude mcp add zendesk -- npx -y @fruggr/zendesk-mcp-server <your-subdomain> --mode single
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
For API token auth, set the env vars before launching Claude Code or add them to your shell profile.
|
|
219
|
+
|
|
220
|
+
</details>
|
|
221
|
+
|
|
222
|
+
<details>
|
|
223
|
+
<summary><strong>VS Code (Copilot / Continue / Cline)</strong></summary>
|
|
224
|
+
|
|
225
|
+
Add to your `.vscode/mcp.json`:
|
|
226
|
+
|
|
227
|
+
```json
|
|
228
|
+
{
|
|
229
|
+
"servers": {
|
|
230
|
+
"zendesk": {
|
|
231
|
+
"command": "npx",
|
|
232
|
+
"args": ["-y", "@fruggr/zendesk-mcp-server", "<your-subdomain>", "--mode", "single"],
|
|
233
|
+
"env": {
|
|
234
|
+
"ZENDESK_EMAIL": "you@example.com",
|
|
235
|
+
"ZENDESK_API_TOKEN": "your-api-token"
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
</details>
|
|
243
|
+
|
|
244
|
+
### CLI reference
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
zendesk-mcp-server <subdomain> [options]
|
|
248
|
+
|
|
249
|
+
Options:
|
|
250
|
+
--mode <mode> single | namespace (default) | all
|
|
251
|
+
--namespace <ns> Filter by namespace (repeatable): tickets, help_center, users
|
|
252
|
+
--tool <name> Filter by tool name (repeatable, forces --mode all)
|
|
253
|
+
--read-only Only expose read operations
|
|
254
|
+
--log-level <level> debug | info (default) | warn | error
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
`--namespace` and `--read-only` are applied before the proxies are registered, so they narrow the surface in every mode — in the default `namespace` mode, `--namespace help_center` registers a single proxy (`zendesk_help_center`) instead of three.
|
|
258
|
+
|
|
259
|
+
**Examples:**
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
# Single tool mode — minimal context, all 36 operations in one tool
|
|
263
|
+
zendesk-mcp-server acme --mode single
|
|
264
|
+
|
|
265
|
+
# Read-only tickets only
|
|
266
|
+
zendesk-mcp-server acme --read-only --namespace tickets
|
|
267
|
+
|
|
268
|
+
# Cherry-pick specific tools
|
|
269
|
+
zendesk-mcp-server acme --tool get_ticket --tool search_tickets --tool get_current_user
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Environment variables
|
|
273
|
+
|
|
274
|
+
| Variable | Required | Default | Description |
|
|
275
|
+
|----------|----------|---------|-------------|
|
|
276
|
+
| `ZENDESK_SUBDOMAIN` | yes (or CLI arg) | — | Zendesk subdomain (e.g., `acme` for acme.zendesk.com) |
|
|
277
|
+
| `ZENDESK_OAUTH_CLIENT_ID` | no | `<subdomain>_zendesk` | OAuth client identifier |
|
|
278
|
+
| `ZENDESK_EMAIL` | for API token auth | — | Agent email for Basic auth |
|
|
279
|
+
| `ZENDESK_API_TOKEN` | for API token auth | — | Zendesk API token |
|
|
280
|
+
| `LOG_LEVEL` | no | `info` | Log verbosity |
|
|
281
|
+
|
|
282
|
+
If both `ZENDESK_EMAIL` and `ZENDESK_API_TOKEN` are set, the server uses API token auth. Otherwise, it uses OAuth 2.1 PKCE.
|
|
283
|
+
|
|
284
|
+
## Development
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
# Install dependencies
|
|
288
|
+
pnpm install
|
|
289
|
+
|
|
290
|
+
# Dev mode (auto-reload)
|
|
291
|
+
ZENDESK_EMAIL=you@example.com ZENDESK_API_TOKEN=xxx \
|
|
292
|
+
pnpm dev -- <your-subdomain> --mode all
|
|
293
|
+
|
|
294
|
+
# Build
|
|
295
|
+
pnpm build
|
|
296
|
+
|
|
297
|
+
# Type-check
|
|
298
|
+
pnpm typecheck
|
|
299
|
+
|
|
300
|
+
# Lint
|
|
301
|
+
pnpm check
|
|
302
|
+
|
|
303
|
+
# Tests
|
|
304
|
+
pnpm test
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## Inspiration & related projects
|
|
308
|
+
|
|
309
|
+
This project was built with reference to:
|
|
310
|
+
- The official [Zendesk API documentation](https://developer.zendesk.com/api-reference/)
|
|
311
|
+
- [mattcoatsworth/zendesk-mcp-server](https://github.com/mattcoatsworth/zendesk-mcp-server)
|
|
312
|
+
- [koundinya/zd-mcp-server](https://github.com/koundinya/zd-mcp-server)
|
|
313
|
+
|
|
314
|
+
## Releases & versioning
|
|
315
|
+
|
|
316
|
+
Versions follow [SemVer](https://semver.org/) and are calculated **automatically** from commit messages — no one bumps the version by hand. Every merge to `main` triggers [semantic-release](https://github.com/semantic-release/semantic-release), which inspects the new [Conventional Commits](https://www.conventionalcommits.org/) since the previous tag, computes the next version, updates [`CHANGELOG.md`](CHANGELOG.md), publishes to npm, and creates the matching GitHub Release.
|
|
317
|
+
|
|
318
|
+
| Commit type | Resulting bump |
|
|
319
|
+
|---|---|
|
|
320
|
+
| `fix:`, `perf:` | patch |
|
|
321
|
+
| `feat:` | minor |
|
|
322
|
+
| `feat!:`, `fix!:`, or a `BREAKING CHANGE:` footer | major |
|
|
323
|
+
| `docs:`, `chore:`, `refactor:`, `test:`, `ci:`, `style:`, `build:` | no release |
|
|
324
|
+
|
|
325
|
+
## Contributing
|
|
326
|
+
|
|
327
|
+
Pull requests are welcome! Whether you write code by hand or with the help of AI, contributions are appreciated.
|
|
328
|
+
|
|
329
|
+
If you'd like to contribute:
|
|
330
|
+
|
|
331
|
+
1. Fork the repository
|
|
332
|
+
2. Create a feature branch
|
|
333
|
+
3. Write tests (we practice TDD)
|
|
334
|
+
4. Use [Conventional Commits](https://www.conventionalcommits.org/) in your commit messages — they directly drive the next version bump
|
|
335
|
+
5. Submit a pull request
|
|
336
|
+
|
|
337
|
+
Please ensure `pnpm check` and `pnpm test` pass before submitting.
|
|
338
|
+
|
|
339
|
+
## License
|
|
340
|
+
|
|
341
|
+
[MIT](LICENSE)
|
package/dist/index.d.ts
ADDED