@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.
- package/dist/index.js +28 -17
- 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:
|
|
5245
|
+
description: buildProxyDescription({
|
|
5246
|
+
title,
|
|
5247
|
+
tools,
|
|
5248
|
+
readOnly: readOnlyMode
|
|
5249
|
+
}),
|
|
5239
5250
|
inputSchema: z.object({
|
|
5240
|
-
operation: z.string().describe(
|
|
5241
|
-
params: z.record(z.string(), z.unknown()).default({}).describe(
|
|
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.
|
|
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.
|
|
74
|
+
"packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f",
|
|
75
75
|
"dependencies": {
|
|
76
76
|
"@modelcontextprotocol/server": "2.1.0",
|
|
77
77
|
"cheerio": "1.2.0",
|