@fruggr/zendesk-mcp-server 3.9.0 → 3.9.1

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/dist/index.js CHANGED
@@ -31398,6 +31398,7 @@ const formatAttachmentSuffix = (count) => count ? ` with ${count} attachment(s)`
31398
31398
  //#endregion
31399
31399
  //#region src/tools/requests.ts
31400
31400
  const forbidden = (tool, endpoint, error, hint) => new Error(`${tool} reads the end-user Requests surface (${endpoint}), which Zendesk serves to a signed-in requester. The current token was refused (HTTP 403). Either the Help Center is closed to this account, or this token is not a Help-Center-enabled user.${hint ? ` ${hint}` : ""} For the agent-side equivalents use create_ticket, get_ticket, list_tickets or add_public_comment (namespace: tickets).`, { cause: error });
31401
+ const END_USER_COMMENT_FORMAT = "Sent as plain text: neither Markdown nor HTML is rendered for an end user (both show as literal text), so write it without formatting markup.";
31401
31402
  const OTHER_USERS_REQUEST_HINT = "A request id that belongs to another user is refused the same way, so check the id is one of your own.";
31402
31403
  /** Run `fetch`, rewriting a 403 into guidance naming the end-user surface. */
31403
31404
  const withForbiddenGuidance = async (tool, endpoint, fetch, hint) => {
@@ -31691,7 +31692,7 @@ const createRequestTools = (env) => {
31691
31692
  description: "Submit a new support request as the signed-in user — the MCP equivalent of the Help Center's \"Submit a request\" form. Returns the created request with its number, which the user can then follow with list_requests and get_request. The submission is checked before sending: an unknown form id, a missing field the form marks required, or a dropdown answer the form does not offer is refused here rather than sent, because Zendesk would answer 201 having silently substituted the default form, accepted an empty subject or dropped the unrecognised value. Call get_request_form first to learn which fields to gather. Priority and type cannot be set by an end user — Zendesk drops them — so triage is left to the agents. This posts as the authenticated user; an agent opening a ticket on someone else's behalf wants create_ticket instead.",
31692
31693
  inputSchema: object({
31693
31694
  subject: string().min(1).describe("One-line summary of the request, shown as the ticket title to the support agents who pick it up."),
31694
- body: string().min(1).describe("The request itself: what happened, what was expected, and any steps to reproduce. Becomes the first public comment on the ticket."),
31695
+ body: string().min(1).describe(`The request itself: what happened, what was expected, and any steps to reproduce. Becomes the first public comment on the ticket. ${END_USER_COMMENT_FORMAT}`),
31695
31696
  form_id: number$1().int().optional().describe("Form id chosen from list_request_forms, deciding which questions apply. Omit to use the account default form."),
31696
31697
  custom_fields: array(object({
31697
31698
  id: number$1().int().describe("Numeric id of a question on the chosen form, from get_request_form."),
@@ -31811,7 +31812,7 @@ const createRequestTools = (env) => {
31811
31812
  description: "Reply on one of the signed-in user's own requests, optionally attaching files. Returns confirmation with the request's status after the reply, which matters because replying on a request that was already solved REOPENS it — Zendesk moves it back to open, and the user should know that is what their message did. The comment is always public: end users cannot post internal notes, and Zendesk silently ignores any attempt to mark one private. A closed request rejects new comments outright. Agents replying to a requester want add_public_comment, or add_private_note for an internal note.",
31812
31813
  inputSchema: object({
31813
31814
  request_id: number$1().int().describe("Number of the request to reply on, as shown by list_requests."),
31814
- body: string().min(1).describe("The message to send. Visible to the support agents on the ticket and included in their email notification."),
31815
+ body: string().min(1).describe(`The message to send. Visible to the support agents on the ticket and included in their email notification. ${END_USER_COMMENT_FORMAT}`),
31815
31816
  attachments: attachmentsParam("Files to attach to this reply, such as a screenshot or a log, with their content base64-encoded.")
31816
31817
  }),
31817
31818
  annotations: {
@@ -32344,6 +32345,7 @@ const formatTicketMetrics = (id, ticket, metric) => {
32344
32345
  };
32345
32346
  //#endregion
32346
32347
  //#region src/tools/tickets.ts
32348
+ const AGENT_COMMENT_FORMAT = "Markdown is rendered (**bold**, lists, links): wrap code, identifiers containing _ or * and <placeholders> in backticks so they show literally. HTML is not rendered (tags show as literal text), so do not send HTML.";
32347
32349
  const MAX_ATTACHMENT_MB = Number.parseFloat((MAX_ATTACHMENT_BYTES / 1048576).toFixed(2));
32348
32350
  const MAX_RESPONSE_MB = Number.parseFloat((MAX_RESPONSE_BYTES / 1048576).toFixed(2));
32349
32351
  const blockCost = (block) => block.type === "image" ? Buffer.byteLength(JSON.stringify({
@@ -32931,7 +32933,7 @@ const createTicketTools = (env) => {
32931
32933
  description: "Create a new Zendesk support ticket with subject, description, and optional priority/type/assignee/tags. The description becomes the first public comment of the ticket, and the new ticket id is returned. After creation, use update_ticket to change status or assignee, add_public_comment or add_private_note to reply, and manage_tags to adjust tags. Look up valid assignee_id / group_id and custom field ids via search_users or your Zendesk admin settings. Discover custom field ids and their accepted option values with list_ticket_fields.",
32932
32934
  inputSchema: object({
32933
32935
  subject: string().min(1).describe("Ticket subject — the short summary line shown in ticket lists and search results."),
32934
- description: string().min(1).describe("Ticket description — the body of the request. It becomes the ticket's first public comment (visible to the requester)."),
32936
+ description: string().min(1).describe(`Ticket description — the body of the request. It becomes the ticket's first public comment (visible to the requester). ${AGENT_COMMENT_FORMAT}`),
32935
32937
  priority: _enum([
32936
32938
  "urgent",
32937
32939
  "high",
@@ -33048,7 +33050,7 @@ const createTicketTools = (env) => {
33048
33050
  description: "Add an internal note (not visible to requester) to a ticket, optionally with file attachments (uploaded via the Zendesk Uploads API and carried on the note). The note is appended to the ticket thread; use add_public_comment instead when the reply should be visible to the requester.",
33049
33051
  inputSchema: object({
33050
33052
  ticket_id: number$1().int().describe("Ticket ID — the numeric id of the ticket to annotate. Obtain it from search_tickets or list_tickets."),
33051
- body: string().min(1).describe("Note text (internal, agent-only). Plain text or HTML; not shown to the requester."),
33053
+ body: string().min(1).describe(`Note text (internal, agent-only); not shown to the requester. ${AGENT_COMMENT_FORMAT}`),
33052
33054
  attachments: attachmentsParam("Files to attach to this note (base64-encoded content).")
33053
33055
  }),
33054
33056
  annotations: {
@@ -33080,7 +33082,7 @@ const createTicketTools = (env) => {
33080
33082
  description: "Add a public comment (visible to requester) to a ticket, optionally with file attachments (uploaded via the Zendesk Uploads API and carried on the comment). The comment is appended to the ticket thread and emails the requester; use add_private_note instead for an internal, agent-only note.",
33081
33083
  inputSchema: object({
33082
33084
  ticket_id: number$1().int().describe("Ticket ID — the numeric id of the ticket to reply on. Obtain it from search_tickets or list_tickets."),
33083
- body: string().min(1).describe("Comment text sent to the requester. Plain text or HTML; visible in the ticket."),
33085
+ body: string().min(1).describe(`Comment text sent to the requester; visible in the ticket. ${AGENT_COMMENT_FORMAT}`),
33084
33086
  attachments: attachmentsParam("Files to attach to this comment (base64-encoded content).")
33085
33087
  }),
33086
33088
  annotations: {
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "bomFormat": "CycloneDX",
3
3
  "specVersion": "1.6",
4
- "serialNumber": "urn:uuid:4adc7c5a-c9ae-5a39-909b-d6f99b8b284c",
4
+ "serialNumber": "urn:uuid:b8422d8d-453c-5e52-8855-b283836a117a",
5
5
  "version": 1,
6
6
  "metadata": {
7
7
  "component": {
8
8
  "type": "application",
9
- "bom-ref": "pkg:npm/%40fruggr/zendesk-mcp-server@3.9.0",
9
+ "bom-ref": "pkg:npm/%40fruggr/zendesk-mcp-server@3.9.1",
10
10
  "name": "@fruggr/zendesk-mcp-server",
11
- "version": "3.9.0",
12
- "purl": "pkg:npm/%40fruggr/zendesk-mcp-server@3.9.0"
11
+ "version": "3.9.1",
12
+ "purl": "pkg:npm/%40fruggr/zendesk-mcp-server@3.9.1"
13
13
  }
14
14
  },
15
15
  "components": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fruggr/zendesk-mcp-server",
3
- "version": "3.9.0",
3
+ "version": "3.9.1",
4
4
  "mcpName": "io.github.fruggr/zendesk-mcp-server",
5
5
  "description": "Deep Zendesk MCP server for your AI assistant: search, draft, update and translate Help Center articles and manage Support tickets end to end — comments, triage and image attachments.",
6
6
  "type": "module",