@fruggr/zendesk-mcp-server 3.1.2 → 3.2.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.
@@ -30,7 +30,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
30
  SOFTWARE.
31
31
  ```
32
32
 
33
- ## @modelcontextprotocol/core@2.1.0
33
+ ## @modelcontextprotocol/core@2.2.0
34
34
 
35
35
  License: MIT
36
36
 
@@ -476,7 +476,7 @@ CC-BY-4.0. See https://creativecommons.org/licenses/by/4.0/legalcode for
476
476
  the full license text.
477
477
  ```
478
478
 
479
- ## @modelcontextprotocol/server@2.1.0
479
+ ## @modelcontextprotocol/server@2.2.0
480
480
 
481
481
  License: MIT
482
482
 
@@ -504,7 +504,7 @@ var getRequestListener = (fetchCallback, options = {}) => {
504
504
  };
505
505
  };
506
506
  //#endregion
507
- //#region node_modules/.pnpm/@modelcontextprotocol+node@2.1.0_@modelcontextprotocol+server@2.1.0_hono@4.13.9/node_modules/@modelcontextprotocol/node/dist/index.mjs
507
+ //#region node_modules/.pnpm/@modelcontextprotocol+node@2.1.0_@modelcontextprotocol+server@2.2.0_hono@4.13.9/node_modules/@modelcontextprotocol/node/dist/index.mjs
508
508
  /**
509
509
  * Server transport for Streamable HTTP: this implements the MCP Streamable HTTP transport specification.
510
510
  * It supports both SSE streaming and direct HTTP responses.
@@ -2264,82 +2264,6 @@ function decodeJwt(jwt) {
2264
2264
  return result;
2265
2265
  }
2266
2266
  //#endregion
2267
- //#region src/auth/server/expiring-map.ts
2268
- /**
2269
- * An in-memory map whose entries lapse after their own TTL. Expired entries are
2270
- * swept on every `set`, so the map stays bounded by what was set within the
2271
- * longest TTL, with no timer to hold the process open.
2272
- */
2273
- const createExpiringMap = () => {
2274
- const entries = /* @__PURE__ */ new Map();
2275
- const get = (key) => {
2276
- const entry = entries.get(key);
2277
- return entry && entry.expiresAt > Date.now() ? entry.value : void 0;
2278
- };
2279
- return {
2280
- set: (key, value, ttlMs) => {
2281
- const now = Date.now();
2282
- for (const [k, entry] of entries) if (entry.expiresAt <= now) entries.delete(k);
2283
- entries.set(key, {
2284
- value,
2285
- expiresAt: now + ttlMs
2286
- });
2287
- },
2288
- get,
2289
- /** Read and forget: a pending value is used at most once. */
2290
- take: (key) => {
2291
- const value = get(key);
2292
- entries.delete(key);
2293
- return value;
2294
- },
2295
- /** Live and not-yet-swept entries. */
2296
- size: () => entries.size
2297
- };
2298
- };
2299
- //#endregion
2300
- //#region src/auth/server/consent.ts
2301
- const hostOf = (uri) => {
2302
- try {
2303
- return new URL(uri).host;
2304
- } catch {
2305
- return uri;
2306
- }
2307
- };
2308
- const SCOPE_LABELS = {
2309
- read: "Read your Zendesk data",
2310
- write: "Create and change Zendesk data on your behalf"
2311
- };
2312
- /**
2313
- * The MCP consent screen, shown once per client that is not trusted (DCR,
2314
- * unknown CIMD, loopback redirects). Names the client, the scopes and where the
2315
- * code goes, per the spec's UI requirements. Every interpolated value is
2316
- * escaped: the client name comes from a document anyone can publish.
2317
- */
2318
- const renderConsentPage = (view) => {
2319
- const name = escapeHtml(view.clientName ?? view.clientId);
2320
- const scopes = view.scopes.map((scope) => `<li>${escapeHtml(SCOPE_LABELS[scope] ?? scope)}</li>`).join("");
2321
- const action = `/interaction/${encodeURIComponent(view.uid)}`;
2322
- return [
2323
- "<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\">",
2324
- "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">",
2325
- "<title>Authorize access to Zendesk</title>",
2326
- "<style>body{font-family:system-ui,sans-serif;max-width:32rem;margin:3rem auto;padding:0 1rem;line-height:1.5}",
2327
- "code{word-break:break-all}button{font:inherit;padding:.5rem 1.25rem;margin-right:.5rem}</style>",
2328
- "</head><body>",
2329
- `<h1>Allow ${name} to use your Zendesk account?</h1>`,
2330
- `<p><strong>${name}</strong> is asking to act as you on <strong>${escapeHtml(view.subdomain)}.zendesk.com</strong>:</p>`,
2331
- `<ul>${scopes}</ul>`,
2332
- `<p>After you allow it, you are sent back to <strong>${escapeHtml(hostOf(view.redirectUri))}</strong>`,
2333
- ` (<code>${escapeHtml(view.redirectUri)}</code>). Only continue if you started this connection yourself.</p>`,
2334
- `<p>Client id: <code>${escapeHtml(view.clientId)}</code></p>`,
2335
- `<form method="post" action="${action}/confirm" style="display:inline"><button type="submit">Allow</button></form>`,
2336
- `<form method="post" action="${action}/abort" style="display:inline"><button type="submit">Deny</button></form>`,
2337
- "</body></html>"
2338
- ].join("");
2339
- };
2340
- /** Plain error page for a failed sign-in. ASCII message, escaped. */
2341
- const renderErrorPage = (title, detail) => `<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Sign-in failed</title></head><body><h1>${escapeHtml(title)}</h1><p>${escapeHtml(detail)}</p></body></html>`;
2342
- //#endregion
2343
2267
  //#region src/auth/server/trusted-clients.ts
2344
2268
  /**
2345
2269
  * Which CIMD clients skip our consent screen, and the fetch shim applied to CIMD
@@ -2425,6 +2349,184 @@ const createCimdFetch = (baseFetch) => async (url, options) => {
2425
2349
  });
2426
2350
  };
2427
2351
  //#endregion
2352
+ //#region src/auth/server/cimd-documents.ts
2353
+ /** How long a kept copy may stand in for its document, after it was kept. */
2354
+ const LAST_GOOD_TTL_S = 604800;
2355
+ const STALE_MAX_AGE_S = 60;
2356
+ const CIMD_FETCH_HINT = "A client document, or a URL it names, could not be fetched: the client cannot sign in or refresh unless a last good copy is served. See https://github.com/fruggr/zendesk-mcp-server/blob/main/docs/troubleshooting.md#http-the-log-shows-oauth_client_fetch_failed";
2357
+ const isTransientFailure = (status) => status === 403 || status === 408 || status === 429 || status >= 500;
2358
+ const messageOf = (err) => {
2359
+ if (!(err instanceof Error)) return String(err);
2360
+ return err.cause instanceof Error ? `${err.message}: ${err.cause.message}` : err.message;
2361
+ };
2362
+ const ownDocument = async (response, url) => {
2363
+ const parsed = await response.json().catch(() => void 0);
2364
+ return parsed?.client_id === url ? parsed : void 0;
2365
+ };
2366
+ /**
2367
+ * A copy is kept when a token is issued, from the client oidc-provider built
2368
+ * and validated: an unauthenticated caller can make the server fetch any URL,
2369
+ * but not write to the grant store, and a rejected document is never kept.
2370
+ */
2371
+ const createCimdDocuments = (baseFetch, { lastGood, logger }) => {
2372
+ const rewrite = createCimdFetch(baseFetch);
2373
+ const stale = /* @__PURE__ */ new Set();
2374
+ const kept = (url) => lastGood.get(url).catch((err) => {
2375
+ logger.warn("oauth_cimd_last_good_read_failed", {
2376
+ url,
2377
+ error: messageOf(err)
2378
+ });
2379
+ });
2380
+ const report = (url, failure, copy) => {
2381
+ logger.warn("oauth_client_fetch_failed", {
2382
+ url,
2383
+ ...failure,
2384
+ fallback: copy ? "last_good" : "none",
2385
+ ...copy && { ageS: Math.floor((Date.now() - copy.fetchedAt) / 1e3) },
2386
+ hint: CIMD_FETCH_HINT
2387
+ });
2388
+ };
2389
+ const serve = (url, copy) => {
2390
+ stale.add(url);
2391
+ return Response.json(copy.document, { headers: { "cache-control": `max-age=${STALE_MAX_AGE_S}` } });
2392
+ };
2393
+ const fallBack = async (url, failure, failed) => {
2394
+ const copy = await kept(url);
2395
+ report(url, failure, copy);
2396
+ if (!copy) return void 0;
2397
+ await failed?.body?.cancel();
2398
+ return serve(url, copy);
2399
+ };
2400
+ const succeeded = async (url, response) => {
2401
+ if (await ownDocument(response.clone(), url) && response.status === 200) {
2402
+ stale.delete(url);
2403
+ return response;
2404
+ }
2405
+ const copy = await kept(url);
2406
+ if (!copy) return response;
2407
+ report(url, {
2408
+ status: response.status,
2409
+ error: "not a client document"
2410
+ }, copy);
2411
+ await response.body?.cancel();
2412
+ return serve(url, copy);
2413
+ };
2414
+ const fetch = async (input, init) => {
2415
+ const url = String(input);
2416
+ let response;
2417
+ try {
2418
+ response = await rewrite(input, init);
2419
+ } catch (err) {
2420
+ const copy = await fallBack(url, { error: messageOf(err) });
2421
+ if (copy) return copy;
2422
+ throw err;
2423
+ }
2424
+ if (response.ok) return succeeded(url, response);
2425
+ if (!isTransientFailure(response.status)) {
2426
+ logger.debug("oauth_client_fetch_failed", {
2427
+ url,
2428
+ status: response.status,
2429
+ fallback: "none"
2430
+ });
2431
+ return response;
2432
+ }
2433
+ return await fallBack(url, { status: response.status }, response) ?? response;
2434
+ };
2435
+ return {
2436
+ fetch,
2437
+ granted: async (client) => {
2438
+ if (client.clientIdMetadataDocument !== true || stale.has(client.clientId)) return;
2439
+ try {
2440
+ await lastGood.set(client.clientId, {
2441
+ document: client.metadata(),
2442
+ fetchedAt: Date.now()
2443
+ }, LAST_GOOD_TTL_S);
2444
+ } catch (err) {
2445
+ logger.warn("oauth_cimd_last_good_store_failed", {
2446
+ url: client.clientId,
2447
+ error: messageOf(err)
2448
+ });
2449
+ }
2450
+ }
2451
+ };
2452
+ };
2453
+ //#endregion
2454
+ //#region src/auth/server/expiring-map.ts
2455
+ /**
2456
+ * An in-memory map whose entries lapse after their own TTL. Expired entries are
2457
+ * swept on every `set`, so the map stays bounded by what was set within the
2458
+ * longest TTL, with no timer to hold the process open.
2459
+ */
2460
+ const createExpiringMap = () => {
2461
+ const entries = /* @__PURE__ */ new Map();
2462
+ const get = (key) => {
2463
+ const entry = entries.get(key);
2464
+ return entry && entry.expiresAt > Date.now() ? entry.value : void 0;
2465
+ };
2466
+ return {
2467
+ set: (key, value, ttlMs) => {
2468
+ const now = Date.now();
2469
+ for (const [k, entry] of entries) if (entry.expiresAt <= now) entries.delete(k);
2470
+ entries.set(key, {
2471
+ value,
2472
+ expiresAt: now + ttlMs
2473
+ });
2474
+ },
2475
+ get,
2476
+ /** Read and forget: a pending value is used at most once. */
2477
+ take: (key) => {
2478
+ const value = get(key);
2479
+ entries.delete(key);
2480
+ return value;
2481
+ },
2482
+ /** Live and not-yet-swept entries. */
2483
+ size: () => entries.size
2484
+ };
2485
+ };
2486
+ //#endregion
2487
+ //#region src/auth/server/consent.ts
2488
+ const hostOf = (uri) => {
2489
+ try {
2490
+ return new URL(uri).host;
2491
+ } catch {
2492
+ return uri;
2493
+ }
2494
+ };
2495
+ const SCOPE_LABELS = {
2496
+ read: "Read your Zendesk data",
2497
+ write: "Create and change Zendesk data on your behalf"
2498
+ };
2499
+ /**
2500
+ * The MCP consent screen, shown once per client that is not trusted (DCR,
2501
+ * unknown CIMD, loopback redirects). Names the client, the scopes and where the
2502
+ * code goes, per the spec's UI requirements. Every interpolated value is
2503
+ * escaped: the client name comes from a document anyone can publish.
2504
+ */
2505
+ const renderConsentPage = (view) => {
2506
+ const name = escapeHtml(view.clientName ?? view.clientId);
2507
+ const scopes = view.scopes.map((scope) => `<li>${escapeHtml(SCOPE_LABELS[scope] ?? scope)}</li>`).join("");
2508
+ const action = `/interaction/${encodeURIComponent(view.uid)}`;
2509
+ return [
2510
+ "<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\">",
2511
+ "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">",
2512
+ "<title>Authorize access to Zendesk</title>",
2513
+ "<style>body{font-family:system-ui,sans-serif;max-width:32rem;margin:3rem auto;padding:0 1rem;line-height:1.5}",
2514
+ "code{word-break:break-all}button{font:inherit;padding:.5rem 1.25rem;margin-right:.5rem}</style>",
2515
+ "</head><body>",
2516
+ `<h1>Allow ${name} to use your Zendesk account?</h1>`,
2517
+ `<p><strong>${name}</strong> is asking to act as you on <strong>${escapeHtml(view.subdomain)}.zendesk.com</strong>:</p>`,
2518
+ `<ul>${scopes}</ul>`,
2519
+ `<p>After you allow it, you are sent back to <strong>${escapeHtml(hostOf(view.redirectUri))}</strong>`,
2520
+ ` (<code>${escapeHtml(view.redirectUri)}</code>). Only continue if you started this connection yourself.</p>`,
2521
+ `<p>Client id: <code>${escapeHtml(view.clientId)}</code></p>`,
2522
+ `<form method="post" action="${action}/confirm" style="display:inline"><button type="submit">Allow</button></form>`,
2523
+ `<form method="post" action="${action}/abort" style="display:inline"><button type="submit">Deny</button></form>`,
2524
+ "</body></html>"
2525
+ ].join("");
2526
+ };
2527
+ /** Plain error page for a failed sign-in. ASCII message, escaped. */
2528
+ const renderErrorPage = (title, detail) => `<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Sign-in failed</title></head><body><h1>${escapeHtml(title)}</h1><p>${escapeHtml(detail)}</p></body></html>`;
2529
+ //#endregion
2428
2530
  //#region src/auth/server/upstream.ts
2429
2531
  /**
2430
2532
  * Zendesk as the upstream identity provider, through the same public PKCE client
@@ -35898,13 +36000,12 @@ const buildProvider = (options) => {
35898
36000
  const { ring, resource } = options;
35899
36001
  const [current] = ring;
35900
36002
  const scopes = options.allowWrite ? RESOURCE_SCOPES.join(" ") : "read";
35901
- const baseFetch = options.fetch ?? ((url, init) => globalThis.fetch(url, init));
35902
36003
  const provider = new lib_default(options.issuer, {
35903
36004
  adapter: options.adapter,
35904
36005
  jwks: { keys: ring.map((set) => set.signingJwk) },
35905
36006
  cookies: { keys: ring.map((set) => set.cookieKey) },
35906
36007
  clients: [],
35907
- fetch: createCimdFetch(baseFetch),
36008
+ fetch: options.cimdDocuments.fetch,
35908
36009
  scopes: options.allowWrite ? [...RESOURCE_SCOPES, "offline_access"] : ["read", "offline_access"],
35909
36010
  clientDefaults: {
35910
36011
  grant_types: ["authorization_code", "refresh_token"],
@@ -36109,6 +36210,10 @@ const createAuthorizationServer = (options) => {
36109
36210
  hint: "Revoked in this process only. Fix the store before restarting: its next successful write persists the removal."
36110
36211
  });
36111
36212
  };
36213
+ const cimdDocuments = createCimdDocuments(options.fetch ?? ((url, init) => globalThis.fetch(url, init)), {
36214
+ lastGood: createSealedCollection(persistent, "CimdDocument", ring),
36215
+ logger
36216
+ });
36112
36217
  const provider = buildProvider({
36113
36218
  issuer,
36114
36219
  resource,
@@ -36118,7 +36223,10 @@ const createAuthorizationServer = (options) => {
36118
36223
  allowWrite: !config.readOnly,
36119
36224
  isAllowedOrigin: options.isAllowedOrigin,
36120
36225
  behindProxy: config.publicUrl?.startsWith("https:") === true,
36121
- fetch: options.fetch
36226
+ cimdDocuments
36227
+ });
36228
+ provider.on("grant.success", (ctx) => {
36229
+ if (ctx.oidc.client) cimdDocuments.granted(ctx.oidc.client);
36122
36230
  });
36123
36231
  provider.on("server_error", (_ctx, err) => {
36124
36232
  logger.error("oauth_server_error", { error: err.message });
package/dist/index.js CHANGED
@@ -7832,7 +7832,7 @@ const loadConfig = (argv = process.argv.slice(2)) => {
7832
7832
  });
7833
7833
  };
7834
7834
  //#endregion
7835
- //#region node_modules/.pnpm/@modelcontextprotocol+server@2.1.0/node_modules/@modelcontextprotocol/server/dist/chunk-Br0eD_fh.mjs
7835
+ //#region node_modules/.pnpm/@modelcontextprotocol+server@2.2.0/node_modules/@modelcontextprotocol/server/dist/chunk-Br0eD_fh.mjs
7836
7836
  var __create = Object.create;
7837
7837
  var __defProp = Object.defineProperty;
7838
7838
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -7864,7 +7864,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
7864
7864
  enumerable: true
7865
7865
  }) : target, mod));
7866
7866
  //#endregion
7867
- //#region node_modules/.pnpm/@modelcontextprotocol+server@2.1.0/node_modules/@modelcontextprotocol/server/dist/dialects-DoSzNhcb.mjs
7867
+ //#region node_modules/.pnpm/@modelcontextprotocol+server@2.2.0/node_modules/@modelcontextprotocol/server/dist/dialects-DoSzNhcb.mjs
7868
7868
  /**
7869
7869
  * Canonical `$schema` URIs per supported dialect (http + https variants, trailing-`#` stripped).
7870
7870
  */
@@ -9447,7 +9447,8 @@ const OAuthTokensSchema = object({
9447
9447
  token_type: string$2(),
9448
9448
  expires_in: number$1().optional(),
9449
9449
  scope: string$2().optional(),
9450
- refresh_token: string$2().optional()
9450
+ refresh_token: string$2().optional(),
9451
+ issuer: string$2().optional().catch(void 0)
9451
9452
  }).strip();
9452
9453
  /**
9453
9454
  * RFC 8693 §2.2.1 Token Exchange response for ID-JAG tokens.
@@ -9504,7 +9505,8 @@ const OAuthClientInformationSchema = object({
9504
9505
  client_id: string$2(),
9505
9506
  client_secret: string$2().optional(),
9506
9507
  client_id_issued_at: number$2().optional(),
9507
- client_secret_expires_at: number$2().optional()
9508
+ client_secret_expires_at: number$2().optional(),
9509
+ issuer: string$2().optional().catch(void 0)
9508
9510
  }).strip();
9509
9511
  /**
9510
9512
  * RFC 7591 OAuth 2.0 Dynamic Client Registration full response (client information plus metadata)
@@ -9525,7 +9527,7 @@ const OAuthTokenRevocationRequestSchema = object({
9525
9527
  token_type_hint: string$2().optional()
9526
9528
  }).strip();
9527
9529
  //#endregion
9528
- //#region node_modules/.pnpm/@modelcontextprotocol+server@2.1.0/node_modules/@modelcontextprotocol/server/dist/src-D-y6h4N7.mjs
9530
+ //#region node_modules/.pnpm/@modelcontextprotocol+server@2.2.0/node_modules/@modelcontextprotocol/server/dist/src-BHSMhZ_W.mjs
9529
9531
  /**
9530
9532
  * Cross-bundle `instanceof` support for the SDK error classes.
9531
9533
  *
@@ -13486,6 +13488,8 @@ const rev2026Codec = {
13486
13488
  const rawInputRequests = raw["inputRequests"];
13487
13489
  const inputRequests = isPlainObject$4(rawInputRequests) ? rawInputRequests : {};
13488
13490
  const requestState = raw["requestState"];
13491
+ const metaParse = raw["_meta"] === void 0 ? void 0 : buildSchemas2026().ResultMetaSchema.safeParse(raw["_meta"]);
13492
+ const meta = metaParse?.success ? metaParse.data : void 0;
13489
13493
  if (Object.keys(inputRequests).length === 0 && typeof requestState !== "string") return {
13490
13494
  kind: "invalid",
13491
13495
  error: new SdkError(SdkErrorCode.InvalidResult, `Invalid result for ${method}: input_required carries neither inputRequests nor requestState (every input_required result must include at least one of the two)`, {
@@ -13496,7 +13500,8 @@ const rev2026Codec = {
13496
13500
  return {
13497
13501
  kind: "input_required",
13498
13502
  inputRequests,
13499
- ...typeof requestState === "string" && { requestState }
13503
+ ...typeof requestState === "string" && { requestState },
13504
+ ...meta !== void 0 && { _meta: meta }
13500
13505
  };
13501
13506
  }
13502
13507
  if (rawResultType !== "complete") return {
@@ -15230,7 +15235,7 @@ var Protocol = class {
15230
15235
  * Emits a notification, which is a one-way message that does not expect a response.
15231
15236
  */
15232
15237
  async notification(notification, options) {
15233
- return this._notificationViaCodec(this._resolveOutboundCodec(notification.method), notification, options);
15238
+ return await this._notificationViaCodec(this._resolveOutboundCodec(notification.method), notification, options);
15234
15239
  }
15235
15240
  /**
15236
15241
  * The notification funnel proper, keyed by the resolved era codec —
@@ -15399,7 +15404,8 @@ function manualInputRequiredValue(decoded) {
15399
15404
  return {
15400
15405
  resultType: "input_required",
15401
15406
  inputRequests: decoded.inputRequests,
15402
- ...decoded.requestState !== void 0 && { requestState: decoded.requestState }
15407
+ ...decoded.requestState !== void 0 && { requestState: decoded.requestState },
15408
+ ...decoded._meta !== void 0 && { _meta: decoded._meta }
15403
15409
  };
15404
15410
  }
15405
15411
  /*!
@@ -15889,7 +15895,7 @@ function normalizeRawShapeSchema(schema) {
15889
15895
  return schema;
15890
15896
  }
15891
15897
  //#endregion
15892
- //#region node_modules/.pnpm/@modelcontextprotocol+server@2.1.0/node_modules/@modelcontextprotocol/server/dist/ajvProvider-CEoC__sr.mjs
15898
+ //#region node_modules/.pnpm/@modelcontextprotocol+server@2.2.0/node_modules/@modelcontextprotocol/server/dist/ajvProvider-CEoC__sr.mjs
15893
15899
  var require_code$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
15894
15900
  Object.defineProperty(exports, "__esModule", { value: true });
15895
15901
  exports.regexpCode = exports.getEsmExportName = exports.getProperty = exports.safeStringify = exports.stringify = exports.strConcat = exports.addCodeArg = exports.str = exports._ = exports.nil = exports._Code = exports.Name = exports.IDENTIFIER = exports._CodeOrName = void 0;
@@ -23024,7 +23030,7 @@ var AjvJsonSchemaValidator = class {
23024
23030
  };
23025
23031
  import_ajv.Ajv;
23026
23032
  //#endregion
23027
- //#region node_modules/.pnpm/@modelcontextprotocol+server@2.1.0/node_modules/@modelcontextprotocol/server/dist/mcp-Dw2OlZ1f.mjs
23033
+ //#region node_modules/.pnpm/@modelcontextprotocol+server@2.2.0/node_modules/@modelcontextprotocol/server/dist/mcp-DYuW2ZSs.mjs
23028
23034
  const COMPLETABLE_SYMBOL = Symbol.for("mcp.completable");
23029
23035
  /**
23030
23036
  * Checks if a schema is completable (has completion metadata).
@@ -24595,7 +24601,7 @@ function unwrapOptionalSchema(schema) {
24595
24601
  return schema.def?.innerType ?? schema;
24596
24602
  }
24597
24603
  //#endregion
24598
- //#region node_modules/.pnpm/@modelcontextprotocol+server@2.1.0/node_modules/@modelcontextprotocol/server/dist/index.mjs
24604
+ //#region node_modules/.pnpm/@modelcontextprotocol+server@2.2.0/node_modules/@modelcontextprotocol/server/dist/index.mjs
24599
24605
  /** Default upper bound, in bytes, on a request body read by the HTTP entry points (4 MiB). */
24600
24606
  const DEFAULT_MAX_REQUEST_BODY_SIZE = 4194304;
24601
24607
  /** Upper bound on the number of messages accepted in one JSON-RPC batch array. */
@@ -106621,7 +106627,7 @@ const createMcpServer = (config, getToken, logger = silentLogger, onUnauthorized
106621
106627
  return server;
106622
106628
  };
106623
106629
  //#endregion
106624
- //#region node_modules/.pnpm/@modelcontextprotocol+server@2.1.0/node_modules/@modelcontextprotocol/server/dist/stdio.mjs
106630
+ //#region node_modules/.pnpm/@modelcontextprotocol+server@2.2.0/node_modules/@modelcontextprotocol/server/dist/stdio.mjs
106625
106631
  /**
106626
106632
  * Marks a stdout `'error'` listener that a closed transport left attached purely to
106627
106633
  * swallow late write failures (see {@link StdioServerTransport.close}). A fresh
@@ -107085,7 +107091,7 @@ const main = async () => {
107085
107091
  return;
107086
107092
  }
107087
107093
  if (config.dev) logger.warn("dev_mode_ignored_http");
107088
- const { startHttpTransport } = await import("./http-CmtU-oNu.js");
107094
+ const { startHttpTransport } = await import("./http-CUsGYeuV.js");
107089
107095
  const http = await startHttpTransport(config, logger);
107090
107096
  installShutdown({
107091
107097
  watchStdin: false,
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "bomFormat": "CycloneDX",
3
3
  "specVersion": "1.6",
4
- "serialNumber": "urn:uuid:a9f47cd2-b8c5-5fd6-81ac-b68c56a7a7f0",
4
+ "serialNumber": "urn:uuid:b370c80f-c327-5c78-b90b-e161da6f00fc",
5
5
  "version": 1,
6
6
  "metadata": {
7
7
  "component": {
8
8
  "type": "application",
9
- "bom-ref": "pkg:npm/%40fruggr/zendesk-mcp-server@3.1.2",
9
+ "bom-ref": "pkg:npm/%40fruggr/zendesk-mcp-server@3.2.0",
10
10
  "name": "@fruggr/zendesk-mcp-server",
11
- "version": "3.1.2",
12
- "purl": "pkg:npm/%40fruggr/zendesk-mcp-server@3.1.2"
11
+ "version": "3.2.0",
12
+ "purl": "pkg:npm/%40fruggr/zendesk-mcp-server@3.2.0"
13
13
  }
14
14
  },
15
15
  "components": [
@@ -27,10 +27,10 @@
27
27
  },
28
28
  {
29
29
  "type": "library",
30
- "bom-ref": "pkg:npm/%40modelcontextprotocol/core@2.1.0",
30
+ "bom-ref": "pkg:npm/%40modelcontextprotocol/core@2.2.0",
31
31
  "name": "@modelcontextprotocol/core",
32
- "version": "2.1.0",
33
- "purl": "pkg:npm/%40modelcontextprotocol/core@2.1.0",
32
+ "version": "2.2.0",
33
+ "purl": "pkg:npm/%40modelcontextprotocol/core@2.2.0",
34
34
  "licenses": [
35
35
  {
36
36
  "expression": "MIT"
@@ -51,10 +51,10 @@
51
51
  },
52
52
  {
53
53
  "type": "library",
54
- "bom-ref": "pkg:npm/%40modelcontextprotocol/server@2.1.0",
54
+ "bom-ref": "pkg:npm/%40modelcontextprotocol/server@2.2.0",
55
55
  "name": "@modelcontextprotocol/server",
56
- "version": "2.1.0",
57
- "purl": "pkg:npm/%40modelcontextprotocol/server@2.1.0",
56
+ "version": "2.2.0",
57
+ "purl": "pkg:npm/%40modelcontextprotocol/server@2.2.0",
58
58
  "licenses": [
59
59
  {
60
60
  "expression": "MIT"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fruggr/zendesk-mcp-server",
3
- "version": "3.1.2",
3
+ "version": "3.2.0",
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",
@@ -75,9 +75,9 @@
75
75
  "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f",
76
76
  "devDependencies": {
77
77
  "@biomejs/biome": "2.5.14",
78
- "@modelcontextprotocol/client": "2.1.0",
78
+ "@modelcontextprotocol/client": "2.2.0",
79
79
  "@modelcontextprotocol/node": "2.1.0",
80
- "@modelcontextprotocol/server": "2.1.0",
80
+ "@modelcontextprotocol/server": "2.2.0",
81
81
  "@semantic-release/changelog": "^7.0.0",
82
82
  "@semantic-release/exec": "^7.1.0",
83
83
  "@semantic-release/git": "^11.0.0",