@fruggr/zendesk-mcp-server 3.0.1 → 3.0.3

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 (2) hide show
  1. package/dist/index.js +28 -17
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -1327,6 +1327,7 @@ const parseSections = (html) => {
1327
1327
  current = {
1328
1328
  heading: $(node).text().trim(),
1329
1329
  headingTag: tagName,
1330
+ headingHtml: $.html(node),
1330
1331
  level,
1331
1332
  contentParts: []
1332
1333
  };
@@ -1344,6 +1345,7 @@ const parseSections = (html) => {
1344
1345
  index: 0,
1345
1346
  heading: "intro",
1346
1347
  headingTag: "",
1348
+ headingHtml: "",
1347
1349
  level: 0,
1348
1350
  html: introHtml,
1349
1351
  wordCount: countWords(textOf(introHtml))
@@ -1355,6 +1357,7 @@ const parseSections = (html) => {
1355
1357
  index: result.length,
1356
1358
  heading: s.heading,
1357
1359
  headingTag: s.headingTag,
1360
+ headingHtml: s.headingHtml,
1358
1361
  level: s.level,
1359
1362
  html: sectionHtml,
1360
1363
  wordCount: countWords(textOf(sectionHtml))
@@ -1365,11 +1368,7 @@ const parseSections = (html) => {
1365
1368
  const replaceSectionContent = (html, sectionIndex, newHtml) => {
1366
1369
  const sections = parseSections(html);
1367
1370
  if (sectionIndex < 0 || sectionIndex >= sections.length) throw new Error(`Section index ${sectionIndex} out of range (valid: 0-${Math.max(0, sections.length - 1)})`);
1368
- return sections.map((section, idx) => {
1369
- const content = idx === sectionIndex ? newHtml : section.html;
1370
- if (section.level === 0) return content;
1371
- return `<${section.headingTag}>${section.heading}</${section.headingTag}>${content}`;
1372
- }).join("");
1371
+ return sections.map((section, idx) => `${section.headingHtml}${idx === sectionIndex ? newHtml : section.html}`).join("");
1373
1372
  };
1374
1373
  const LEADING_HEADING = /^\s*<(h[1-3])(?:\s[^>]*)?>([\s\S]*?)<\/\1\s*>/i;
1375
1374
  const normalizeText = (text) => text.trim().split(WHITESPACE_RUN).join(" ");
@@ -2083,6 +2082,23 @@ const createTopologyProvider = (getToken, subdomain, onUnauthorized) => {
2083
2082
  return promise;
2084
2083
  } };
2085
2084
  };
2085
+ const PARAMS_FIELD_DESCRIPTION = "Parameters of the chosen operation, named exactly as its line in \"operation\" lists them (* = required). An unknown name is rejected.";
2086
+ const summarizeDescription = (description) => {
2087
+ const idx = description.indexOf(". ");
2088
+ if (idx === -1) return description;
2089
+ return description.slice(0, idx + 1);
2090
+ };
2091
+ const operationSignature = (tool) => {
2092
+ const params = Object.entries(tool.inputSchema.shape).map(([key, field]) => field.safeParse(void 0).success ? key : `${key}*`);
2093
+ return `${tool.name}(${params.join(", ")})`;
2094
+ };
2095
+ const buildOperationList = (tools) => tools.map((t) => `- ${operationSignature(t)}: ${summarizeDescription(t.description)}${t.readOnly ? "" : " (write)"}`).join("\n");
2096
+ const buildOperationFieldDescription = (tools) => `One of the operations below. Each line reads name(parameters): summary, where the parameters are the exact names "params" accepts and * marks a required one; (write) marks an operation that changes data.\n${buildOperationList(tools)}`;
2097
+ const buildProxyDescription = ({ title, tools, readOnly }) => {
2098
+ const head = `${readOnly ? "[RO] " : ""}${title}. Specify the operation and its parameters. The "operation" field lists every operation with a one-line summary and the parameter names "params" accepts (* = required); an unknown parameter is rejected with the list of valid ones.`;
2099
+ const withNames = `${head}\n\nOperations: ${tools.map((t) => t.name).join(", ")}`;
2100
+ return withNames.length <= 2048 ? withNames : head;
2101
+ };
2086
2102
  //#endregion
2087
2103
  //#region src/routing/registry.ts
2088
2104
  /**
@@ -5198,12 +5214,6 @@ const runHandler = async (def, params, onUnauthorized) => {
5198
5214
  throw err;
5199
5215
  }
5200
5216
  };
5201
- const summarizeDescription = (description) => {
5202
- const idx = description.indexOf(". ");
5203
- if (idx === -1) return description;
5204
- return description.slice(0, idx + 1);
5205
- };
5206
- const buildOperationList = (tools) => tools.map((t) => `- **${t.name}**: ${summarizeDescription(t.description)}${t.readOnly ? "" : " (write)"}`).join("\n");
5207
5217
  const aggregateAnnotations = (tools) => ({
5208
5218
  readOnlyHint: tools.every((t) => t.annotations.readOnlyHint),
5209
5219
  destructiveHint: tools.some((t) => t.annotations.destructiveHint),
@@ -5228,17 +5238,18 @@ const buildProxyDispatch = (tools, onUnauthorized) => {
5228
5238
  };
5229
5239
  };
5230
5240
  const registerProxyTool = (server, toolName, title, tools, readOnlyMode, onUnauthorized) => {
5231
- const operationNames = tools.map((t) => t.name);
5232
- const operationList = buildOperationList(tools);
5233
5241
  const annotations = aggregateAnnotations(tools);
5234
- const prefix = readOnlyMode ? "[RO] " : "";
5235
5242
  const dispatch = buildProxyDispatch(tools, onUnauthorized);
5236
5243
  return server.registerTool(toolName, {
5237
5244
  title,
5238
- description: `${prefix}${title}. Specify the operation and its parameters.\n\nAvailable operations:\n${operationList}`,
5245
+ description: buildProxyDescription({
5246
+ title,
5247
+ tools,
5248
+ readOnly: readOnlyMode
5249
+ }),
5239
5250
  inputSchema: z.object({
5240
- operation: z.string().describe(`One of: ${operationNames.join(", ")}`),
5241
- params: z.record(z.string(), z.unknown()).default({}).describe("Operation parameters")
5251
+ operation: z.string().describe(buildOperationFieldDescription(tools)),
5252
+ params: z.record(z.string(), z.unknown()).default({}).describe(PARAMS_FIELD_DESCRIPTION)
5242
5253
  }),
5243
5254
  annotations
5244
5255
  }, async (args) => dispatch(args));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fruggr/zendesk-mcp-server",
3
- "version": "3.0.1",
3
+ "version": "3.0.3",
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",
@@ -71,7 +71,7 @@
71
71
  "engines": {
72
72
  "node": ">=22"
73
73
  },
74
- "packageManager": "pnpm@12.6.0+sha512.3ef68f951cb111ac204b4a5a16f0b2ddf0da56a96e0413e81d855d9f0b55ef926714709028e1cd00c405c2c5fb7b9e8ec4dc46777c805d0373c2f2ff00fd20ec",
74
+ "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f",
75
75
  "dependencies": {
76
76
  "@modelcontextprotocol/server": "2.1.0",
77
77
  "cheerio": "1.2.0",