@wellforce/zendesk-mcp 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.
Files changed (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +130 -0
  3. package/dist/src/client/types.d.ts +160 -0
  4. package/dist/src/client/types.js +2 -0
  5. package/dist/src/client/types.js.map +1 -0
  6. package/dist/src/client/zendesk-client.d.ts +13 -0
  7. package/dist/src/client/zendesk-client.js +79 -0
  8. package/dist/src/client/zendesk-client.js.map +1 -0
  9. package/dist/src/config.d.ts +8 -0
  10. package/dist/src/config.js +27 -0
  11. package/dist/src/config.js.map +1 -0
  12. package/dist/src/index.d.ts +2 -0
  13. package/dist/src/index.js +39 -0
  14. package/dist/src/index.js.map +1 -0
  15. package/dist/src/tools/auth.d.ts +3 -0
  16. package/dist/src/tools/auth.js +48 -0
  17. package/dist/src/tools/auth.js.map +1 -0
  18. package/dist/src/tools/automations.d.ts +3 -0
  19. package/dist/src/tools/automations.js +146 -0
  20. package/dist/src/tools/automations.js.map +1 -0
  21. package/dist/src/tools/comments.d.ts +3 -0
  22. package/dist/src/tools/comments.js +47 -0
  23. package/dist/src/tools/comments.js.map +1 -0
  24. package/dist/src/tools/groups.d.ts +3 -0
  25. package/dist/src/tools/groups.js +86 -0
  26. package/dist/src/tools/groups.js.map +1 -0
  27. package/dist/src/tools/index.d.ts +3 -0
  28. package/dist/src/tools/index.js +25 -0
  29. package/dist/src/tools/index.js.map +1 -0
  30. package/dist/src/tools/macros.d.ts +3 -0
  31. package/dist/src/tools/macros.js +56 -0
  32. package/dist/src/tools/macros.js.map +1 -0
  33. package/dist/src/tools/organizations.d.ts +3 -0
  34. package/dist/src/tools/organizations.js +105 -0
  35. package/dist/src/tools/organizations.js.map +1 -0
  36. package/dist/src/tools/search.d.ts +3 -0
  37. package/dist/src/tools/search.js +41 -0
  38. package/dist/src/tools/search.js.map +1 -0
  39. package/dist/src/tools/tickets.d.ts +3 -0
  40. package/dist/src/tools/tickets.js +167 -0
  41. package/dist/src/tools/tickets.js.map +1 -0
  42. package/dist/src/tools/triggers.d.ts +3 -0
  43. package/dist/src/tools/triggers.js +144 -0
  44. package/dist/src/tools/triggers.js.map +1 -0
  45. package/dist/src/tools/users.d.ts +3 -0
  46. package/dist/src/tools/users.js +107 -0
  47. package/dist/src/tools/users.js.map +1 -0
  48. package/dist/src/tools/views.d.ts +3 -0
  49. package/dist/src/tools/views.js +79 -0
  50. package/dist/src/tools/views.js.map +1 -0
  51. package/dist/src/utils/errors.d.ts +13 -0
  52. package/dist/src/utils/errors.js +31 -0
  53. package/dist/src/utils/errors.js.map +1 -0
  54. package/package.json +53 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Wellforce IT
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,130 @@
1
+ # @wellforce/zendesk-mcp
2
+
3
+ A Zendesk MCP server for Claude Desktop. Gives Claude access to 41 Zendesk tools — manage tickets, users, organizations, and more through natural language.
4
+
5
+ ## Installation
6
+
7
+ Add to your Claude Desktop config file:
8
+
9
+ - **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
10
+ - **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
11
+
12
+ ```json
13
+ {
14
+ "mcpServers": {
15
+ "zendesk": {
16
+ "command": "npx",
17
+ "args": ["-y", "@wellforce/zendesk-mcp"],
18
+ "env": {
19
+ "ZENDESK_SUBDOMAIN": "yourcompany",
20
+ "ZENDESK_EMAIL": "you@yourcompany.com",
21
+ "ZENDESK_TOKEN": "your_api_token"
22
+ }
23
+ }
24
+ }
25
+ }
26
+ ```
27
+
28
+ Restart Claude Desktop. You should see a hammer icon with 41 tools available.
29
+
30
+ ## Getting Your API Token
31
+
32
+ 1. Log into Zendesk as an admin
33
+ 2. Go to **Admin Center > Apps and Integrations > Zendesk API**
34
+ 3. Click **Add API token**
35
+ 4. Copy the token — you won't be able to see it again
36
+
37
+ ## Environment Variables
38
+
39
+ | Variable | Description | Example |
40
+ |----------|-------------|---------|
41
+ | `ZENDESK_SUBDOMAIN` | Your Zendesk subdomain | `acme` (from `acme.zendesk.com`) |
42
+ | `ZENDESK_EMAIL` | Your Zendesk agent email | `you@acme.com` |
43
+ | `ZENDESK_TOKEN` | Your Zendesk API token | See above |
44
+
45
+ ## Available Tools (41)
46
+
47
+ ### Tickets
48
+ - `zendesk_list_tickets` — List tickets with status/assignee/requester filters
49
+ - `zendesk_get_ticket` — Get a single ticket by ID
50
+ - `zendesk_create_ticket` — Create a new ticket
51
+ - `zendesk_update_ticket` — Update ticket properties
52
+ - `zendesk_delete_ticket` — Delete a ticket (soft delete)
53
+
54
+ ### Comments
55
+ - `zendesk_list_comments` — List all comments on a ticket
56
+ - `zendesk_add_comment` — Add a public reply or internal note
57
+
58
+ ### Users
59
+ - `zendesk_list_users` — List users with optional role filter
60
+ - `zendesk_get_user` — Get a user by ID
61
+ - `zendesk_create_user` — Create a new user
62
+ - `zendesk_update_user` — Update user properties
63
+ - `zendesk_delete_user` — Delete a user (soft delete)
64
+
65
+ ### Organizations
66
+ - `zendesk_list_organizations` — List all organizations
67
+ - `zendesk_get_organization` — Get an organization by ID
68
+ - `zendesk_create_organization` — Create a new organization
69
+ - `zendesk_update_organization` — Update organization properties
70
+ - `zendesk_delete_organization` — Delete an organization
71
+
72
+ ### Groups
73
+ - `zendesk_list_groups` — List all groups
74
+ - `zendesk_get_group` — Get a group by ID
75
+ - `zendesk_create_group` — Create a new group
76
+ - `zendesk_update_group` — Update group properties
77
+ - `zendesk_delete_group` — Delete a group
78
+
79
+ ### Views
80
+ - `zendesk_list_views` — List all views
81
+ - `zendesk_get_view` — Get a view by ID
82
+ - `zendesk_list_view_tickets` — List tickets in a view
83
+ - `zendesk_count_view_tickets` — Count tickets in a view
84
+
85
+ ### Macros
86
+ - `zendesk_list_macros` — List all macros
87
+ - `zendesk_get_macro` — Get a macro by ID
88
+ - `zendesk_apply_macro` — Apply a macro to a ticket
89
+
90
+ ### Triggers
91
+ - `zendesk_list_triggers` — List all triggers
92
+ - `zendesk_get_trigger` — Get a trigger by ID
93
+ - `zendesk_create_trigger` — Create a new trigger
94
+ - `zendesk_update_trigger` — Update trigger properties
95
+ - `zendesk_delete_trigger` — Delete a trigger
96
+
97
+ ### Automations
98
+ - `zendesk_list_automations` — List all automations
99
+ - `zendesk_get_automation` — Get an automation by ID
100
+ - `zendesk_create_automation` — Create a new automation
101
+ - `zendesk_update_automation` — Update automation properties
102
+ - `zendesk_delete_automation` — Delete an automation
103
+
104
+ ### Search
105
+ - `zendesk_search` — Search across tickets, users, and organizations
106
+
107
+ ### Auth
108
+ - `zendesk_whoami` — Check current authenticated identity
109
+
110
+ ## Development
111
+
112
+ ```bash
113
+ git clone https://github.com/wellforce/zendesk-mcp.git
114
+ cd zendesk-mcp
115
+ npm install
116
+ npm run build
117
+ npm test
118
+ ```
119
+
120
+ ```bash
121
+ # Watch mode
122
+ npm run dev
123
+
124
+ # Test with MCP Inspector
125
+ npm run inspect
126
+ ```
127
+
128
+ ## License
129
+
130
+ MIT
@@ -0,0 +1,160 @@
1
+ export interface ZendeskTicket {
2
+ id: number;
3
+ subject: string;
4
+ description: string;
5
+ status: "new" | "open" | "pending" | "hold" | "solved" | "closed";
6
+ priority: "urgent" | "high" | "normal" | "low" | null;
7
+ type: "problem" | "incident" | "question" | "task" | null;
8
+ requester_id: number;
9
+ assignee_id: number | null;
10
+ group_id: number | null;
11
+ organization_id: number | null;
12
+ tags: string[];
13
+ custom_fields: Array<{
14
+ id: number;
15
+ value: unknown;
16
+ }>;
17
+ created_at: string;
18
+ updated_at: string;
19
+ }
20
+ export interface ZendeskComment {
21
+ id: number;
22
+ body: string;
23
+ html_body: string;
24
+ public: boolean;
25
+ author_id: number;
26
+ created_at: string;
27
+ }
28
+ export interface ZendeskUser {
29
+ id: number;
30
+ name: string;
31
+ email: string;
32
+ role: "end-user" | "agent" | "admin";
33
+ organization_id: number | null;
34
+ phone: string | null;
35
+ tags: string[];
36
+ created_at: string;
37
+ updated_at: string;
38
+ }
39
+ export interface ZendeskOrganization {
40
+ id: number;
41
+ name: string;
42
+ domain_names: string[];
43
+ tags: string[];
44
+ notes: string;
45
+ details: string;
46
+ created_at: string;
47
+ updated_at: string;
48
+ }
49
+ export interface ZendeskGroup {
50
+ id: number;
51
+ name: string;
52
+ description: string;
53
+ default: boolean;
54
+ created_at: string;
55
+ updated_at: string;
56
+ }
57
+ export interface ZendeskView {
58
+ id: number;
59
+ title: string;
60
+ active: boolean;
61
+ description: string;
62
+ position: number;
63
+ restriction: {
64
+ type: string;
65
+ id?: number;
66
+ } | null;
67
+ conditions: unknown;
68
+ output: unknown;
69
+ created_at: string;
70
+ updated_at: string;
71
+ }
72
+ export interface ZendeskViewCount {
73
+ view_id: number;
74
+ url: string;
75
+ value: number;
76
+ pretty: string;
77
+ fresh: boolean;
78
+ }
79
+ export interface ZendeskMacro {
80
+ id: number;
81
+ title: string;
82
+ active: boolean;
83
+ description: string | null;
84
+ actions: Array<{
85
+ field: string;
86
+ value: unknown;
87
+ }>;
88
+ restriction: {
89
+ type: string;
90
+ id?: number;
91
+ } | null;
92
+ position: number;
93
+ created_at: string;
94
+ updated_at: string;
95
+ }
96
+ export interface ZendeskTrigger {
97
+ id: number;
98
+ title: string;
99
+ active: boolean;
100
+ description: string | null;
101
+ conditions: {
102
+ all: Array<{
103
+ field: string;
104
+ operator: string;
105
+ value: unknown;
106
+ }>;
107
+ any: Array<{
108
+ field: string;
109
+ operator: string;
110
+ value: unknown;
111
+ }>;
112
+ };
113
+ actions: Array<{
114
+ field: string;
115
+ value: unknown;
116
+ }>;
117
+ position: number;
118
+ created_at: string;
119
+ updated_at: string;
120
+ }
121
+ export interface ZendeskAutomation {
122
+ id: number;
123
+ title: string;
124
+ active: boolean;
125
+ description: string | null;
126
+ conditions: {
127
+ all: Array<{
128
+ field: string;
129
+ operator: string;
130
+ value: unknown;
131
+ }>;
132
+ any: Array<{
133
+ field: string;
134
+ operator: string;
135
+ value: unknown;
136
+ }>;
137
+ };
138
+ actions: Array<{
139
+ field: string;
140
+ value: unknown;
141
+ }>;
142
+ position: number;
143
+ created_at: string;
144
+ updated_at: string;
145
+ }
146
+ export interface PaginatedResponse<T> {
147
+ results?: T[];
148
+ tickets?: T[];
149
+ users?: T[];
150
+ organizations?: T[];
151
+ comments?: T[];
152
+ groups?: T[];
153
+ views?: T[];
154
+ macros?: T[];
155
+ triggers?: T[];
156
+ automations?: T[];
157
+ count: number;
158
+ next_page: string | null;
159
+ previous_page: string | null;
160
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/client/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ import { ZendeskConfig } from "../config.js";
2
+ export declare class ZendeskClient {
3
+ private http;
4
+ private currentEmail;
5
+ constructor(config: ZendeskConfig);
6
+ reconfigure(config: ZendeskConfig): void;
7
+ getAuthenticatedEmail(): string;
8
+ get<T>(path: string, params?: Record<string, unknown>): Promise<T>;
9
+ post<T>(path: string, data: unknown): Promise<T>;
10
+ put<T>(path: string, data: unknown): Promise<T>;
11
+ delete(path: string): Promise<void>;
12
+ private wrapError;
13
+ }
@@ -0,0 +1,79 @@
1
+ import axios, { AxiosError } from "axios";
2
+ import { ZendeskApiError } from "../utils/errors.js";
3
+ export class ZendeskClient {
4
+ http;
5
+ currentEmail;
6
+ constructor(config) {
7
+ this.currentEmail = config.email;
8
+ this.http = axios.create({
9
+ baseURL: config.baseUrl,
10
+ auth: {
11
+ username: `${config.email}/token`,
12
+ password: config.token,
13
+ },
14
+ headers: { "Content-Type": "application/json" },
15
+ timeout: 30000,
16
+ });
17
+ }
18
+ reconfigure(config) {
19
+ this.currentEmail = config.email;
20
+ this.http = axios.create({
21
+ baseURL: config.baseUrl,
22
+ auth: {
23
+ username: `${config.email}/token`,
24
+ password: config.token,
25
+ },
26
+ headers: { "Content-Type": "application/json" },
27
+ timeout: 30000,
28
+ });
29
+ }
30
+ getAuthenticatedEmail() {
31
+ return this.currentEmail;
32
+ }
33
+ async get(path, params) {
34
+ try {
35
+ const response = await this.http.get(path, { params });
36
+ return response.data;
37
+ }
38
+ catch (error) {
39
+ throw this.wrapError(error, `GET ${path}`);
40
+ }
41
+ }
42
+ async post(path, data) {
43
+ try {
44
+ const response = await this.http.post(path, data);
45
+ return response.data;
46
+ }
47
+ catch (error) {
48
+ throw this.wrapError(error, `POST ${path}`);
49
+ }
50
+ }
51
+ async put(path, data) {
52
+ try {
53
+ const response = await this.http.put(path, data);
54
+ return response.data;
55
+ }
56
+ catch (error) {
57
+ throw this.wrapError(error, `PUT ${path}`);
58
+ }
59
+ }
60
+ async delete(path) {
61
+ try {
62
+ await this.http.delete(path);
63
+ }
64
+ catch (error) {
65
+ throw this.wrapError(error, `DELETE ${path}`);
66
+ }
67
+ }
68
+ wrapError(error, endpoint) {
69
+ if (error instanceof AxiosError) {
70
+ const status = error.response?.status ?? 0;
71
+ const data = error.response?.data;
72
+ const message = data?.error ?? data?.description ?? error.message ?? "Request failed";
73
+ return new ZendeskApiError(message, status, endpoint, data);
74
+ }
75
+ const message = error instanceof Error ? error.message : "Unknown error";
76
+ return new ZendeskApiError(message, 0, endpoint);
77
+ }
78
+ }
79
+ //# sourceMappingURL=zendesk-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zendesk-client.js","sourceRoot":"","sources":["../../../src/client/zendesk-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAiB,UAAU,EAAE,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,OAAO,aAAa;IAChB,IAAI,CAAgB;IACpB,YAAY,CAAS;IAE7B,YAAY,MAAqB;QAC/B,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC;YACvB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,IAAI,EAAE;gBACJ,QAAQ,EAAE,GAAG,MAAM,CAAC,KAAK,QAAQ;gBACjC,QAAQ,EAAE,MAAM,CAAC,KAAK;aACvB;YACD,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;IACL,CAAC;IAED,WAAW,CAAC,MAAqB;QAC/B,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC;YACvB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,IAAI,EAAE;gBACJ,QAAQ,EAAE,GAAG,MAAM,CAAC,KAAK,QAAQ;gBACjC,QAAQ,EAAE,MAAM,CAAC,KAAK;aACvB;YACD,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;IACL,CAAC;IAED,qBAAqB;QACnB,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,GAAG,CAAI,IAAY,EAAE,MAAgC;QACzD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAI,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;YAC1D,OAAO,QAAQ,CAAC,IAAI,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAI,IAAY,EAAE,IAAa;QACvC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAI,IAAI,EAAE,IAAI,CAAC,CAAC;YACrD,OAAO,QAAQ,CAAC,IAAI,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAG,CAAI,IAAY,EAAE,IAAa;QACtC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAI,IAAI,EAAE,IAAI,CAAC,CAAC;YACpD,OAAO,QAAQ,CAAC,IAAI,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,IAAI,EAAE,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAEO,SAAS,CAAC,KAAc,EAAE,QAAgB;QAChD,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;YAChC,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC;YAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC;YAClC,MAAM,OAAO,GACX,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,WAAW,IAAI,KAAK,CAAC,OAAO,IAAI,gBAAgB,CAAC;YACxE,OAAO,IAAI,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACzE,OAAO,IAAI,eAAe,CAAC,OAAO,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;IACnD,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ export interface ZendeskConfig {
2
+ subdomain: string;
3
+ email: string;
4
+ token: string;
5
+ baseUrl: string;
6
+ }
7
+ export declare function loadConfig(): ZendeskConfig;
8
+ export declare function loadSubdomain(): string;
@@ -0,0 +1,27 @@
1
+ export function loadConfig() {
2
+ const subdomain = process.env.ZENDESK_SUBDOMAIN;
3
+ const email = process.env.ZENDESK_EMAIL;
4
+ const token = process.env.ZENDESK_TOKEN;
5
+ if (!subdomain || !email || !token) {
6
+ const missing = [
7
+ !subdomain && "ZENDESK_SUBDOMAIN",
8
+ !email && "ZENDESK_EMAIL",
9
+ !token && "ZENDESK_TOKEN",
10
+ ].filter(Boolean);
11
+ throw new Error(`Missing required environment variables: ${missing.join(", ")}`);
12
+ }
13
+ return {
14
+ subdomain,
15
+ email,
16
+ token,
17
+ baseUrl: `https://${subdomain}.zendesk.com/api/v2`,
18
+ };
19
+ }
20
+ export function loadSubdomain() {
21
+ const subdomain = process.env.ZENDESK_SUBDOMAIN;
22
+ if (!subdomain) {
23
+ throw new Error("Missing required environment variable: ZENDESK_SUBDOMAIN");
24
+ }
25
+ return subdomain;
26
+ }
27
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,UAAU;IACxB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAChD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IACxC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAExC,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG;YACd,CAAC,SAAS,IAAI,mBAAmB;YACjC,CAAC,KAAK,IAAI,eAAe;YACzB,CAAC,KAAK,IAAI,eAAe;SAC1B,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,2CAA2C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAChE,CAAC;IACJ,CAAC;IAED,OAAO;QACL,SAAS;QACT,KAAK;QACL,KAAK;QACL,OAAO,EAAE,WAAW,SAAS,qBAAqB;KACnD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAChD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { ZendeskClient } from "./client/zendesk-client.js";
5
+ import { registerAllTools } from "./tools/index.js";
6
+ async function main() {
7
+ const subdomain = process.env.ZENDESK_SUBDOMAIN;
8
+ const email = process.env.ZENDESK_EMAIL;
9
+ const token = process.env.ZENDESK_TOKEN;
10
+ const missing = [
11
+ !subdomain && "ZENDESK_SUBDOMAIN",
12
+ !email && "ZENDESK_EMAIL",
13
+ !token && "ZENDESK_TOKEN",
14
+ ].filter(Boolean);
15
+ if (!subdomain || !email || !token) {
16
+ console.error(`Missing required environment variables: ${missing.join(", ")}\n` +
17
+ "Set these in the \"env\" block of your claude_desktop_config.json.");
18
+ process.exit(1);
19
+ }
20
+ const config = {
21
+ subdomain,
22
+ email,
23
+ token,
24
+ baseUrl: `https://${subdomain}.zendesk.com/api/v2`,
25
+ };
26
+ const client = new ZendeskClient(config);
27
+ const server = new McpServer({
28
+ name: "@wellforce/zendesk-mcp",
29
+ version: "1.0.0",
30
+ });
31
+ registerAllTools(server, client, subdomain);
32
+ const transport = new StdioServerTransport();
33
+ await server.connect(transport);
34
+ }
35
+ main().catch((error) => {
36
+ console.error("Fatal error:", error);
37
+ process.exit(1);
38
+ });
39
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAChD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IACxC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAExC,MAAM,OAAO,GAAG;QACd,CAAC,SAAS,IAAI,mBAAmB;QACjC,CAAC,KAAK,IAAI,eAAe;QACzB,CAAC,KAAK,IAAI,eAAe;KAC1B,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElB,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;QACnC,OAAO,CAAC,KAAK,CACX,2CAA2C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YAC/D,oEAAoE,CACvE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG;QACb,SAAS;QACT,KAAK;QACL,KAAK;QACL,OAAO,EAAE,WAAW,SAAS,qBAAqB;KACnD,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;IAEzC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,wBAAwB;QAC9B,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IAE5C,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { ZendeskClient } from "../client/zendesk-client.js";
3
+ export declare function registerAuthTools(server: McpServer, client: ZendeskClient, subdomain: string): void;
@@ -0,0 +1,48 @@
1
+ import { z } from "zod";
2
+ import { formatErrorResponse } from "../utils/errors.js";
3
+ export function registerAuthTools(server, client, subdomain) {
4
+ server.tool("zendesk_authenticate", "Authenticate as a specific Zendesk agent. Call this at the start of a session to set who actions are performed as. Verifies credentials by fetching the authenticated user profile.", {
5
+ email: z.string().email().describe("Your Zendesk agent email address"),
6
+ token: z.string().describe("Your personal Zendesk API token"),
7
+ }, async ({ email, token }) => {
8
+ try {
9
+ const config = {
10
+ subdomain,
11
+ email,
12
+ token,
13
+ baseUrl: `https://${subdomain}.zendesk.com/api/v2`,
14
+ };
15
+ client.reconfigure(config);
16
+ // Verify credentials by fetching the authenticated user
17
+ const result = await client.get("/users/me.json");
18
+ return {
19
+ content: [
20
+ {
21
+ type: "text",
22
+ text: `Authenticated successfully as ${result.user.name} (${result.user.email}, role: ${result.user.role}). All subsequent actions will be performed as this user.`,
23
+ },
24
+ ],
25
+ };
26
+ }
27
+ catch (error) {
28
+ return formatErrorResponse(error);
29
+ }
30
+ });
31
+ server.tool("zendesk_whoami", "Check which Zendesk user is currently authenticated", {}, async () => {
32
+ try {
33
+ const result = await client.get("/users/me.json");
34
+ return {
35
+ content: [
36
+ {
37
+ type: "text",
38
+ text: `Currently authenticated as ${result.user.name} (${result.user.email}, role: ${result.user.role}).`,
39
+ },
40
+ ],
41
+ };
42
+ }
43
+ catch (error) {
44
+ return formatErrorResponse(error);
45
+ }
46
+ });
47
+ }
48
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/tools/auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,UAAU,iBAAiB,CAC/B,MAAiB,EACjB,MAAqB,EACrB,SAAiB;IAEjB,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,qLAAqL,EACrL;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;QACtE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;KAC9D,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE;QACzB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG;gBACb,SAAS;gBACT,KAAK;gBACL,KAAK;gBACL,OAAO,EAAE,WAAW,SAAS,qBAAqB;aACnD,CAAC;YAEF,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YAE3B,wDAAwD;YACxD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAC7B,gBAAgB,CACjB,CAAC;YAEF,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,iCAAiC,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,KAAK,WAAW,MAAM,CAAC,IAAI,CAAC,IAAI,2DAA2D;qBACpK;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,qDAAqD,EACrD,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAC7B,gBAAgB,CACjB,CAAC;YACF,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,8BAA8B,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,KAAK,WAAW,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI;qBAC1G;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { ZendeskClient } from "../client/zendesk-client.js";
3
+ export declare function registerAutomationTools(server: McpServer, client: ZendeskClient): void;