@mcpc-tech/cli 0.1.52 → 0.1.54

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/server.mjs CHANGED
@@ -551,10 +551,9 @@ var ProgressTokenSchema = z.union([z.string(), z.number().int()]);
551
551
  var CursorSchema = z.string();
552
552
  var TaskCreationParamsSchema = z.looseObject({
553
553
  /**
554
- * Time in milliseconds to keep task results available after completion.
555
- * If null, the task has unlimited lifetime until manually cleaned up.
554
+ * Requested duration in milliseconds to retain task from creation.
556
555
  */
557
- ttl: z.union([z.number(), z.null()]).optional(),
556
+ ttl: z.number().optional(),
558
557
  /**
559
558
  * Time in milliseconds to wait between task status requests.
560
559
  */
@@ -854,7 +853,11 @@ var ClientCapabilitiesSchema = z.object({
854
853
  /**
855
854
  * Present if the client supports task creation.
856
855
  */
857
- tasks: ClientTasksCapabilitySchema.optional()
856
+ tasks: ClientTasksCapabilitySchema.optional(),
857
+ /**
858
+ * Extensions that the client supports. Keys are extension identifiers (vendor-prefix/extension-name).
859
+ */
860
+ extensions: z.record(z.string(), AssertObjectSchema).optional()
858
861
  });
859
862
  var InitializeRequestParamsSchema = BaseRequestParamsSchema.extend({
860
863
  /**
@@ -916,7 +919,11 @@ var ServerCapabilitiesSchema = z.object({
916
919
  /**
917
920
  * Present if the server supports task creation.
918
921
  */
919
- tasks: ServerTasksCapabilitySchema.optional()
922
+ tasks: ServerTasksCapabilitySchema.optional(),
923
+ /**
924
+ * Extensions that the server supports. Keys are extension identifiers (vendor-prefix/extension-name).
925
+ */
926
+ extensions: z.record(z.string(), AssertObjectSchema).optional()
920
927
  });
921
928
  var InitializeResultSchema = ResultSchema.extend({
922
929
  /**
@@ -1109,6 +1116,12 @@ var ResourceSchema = z.object({
1109
1116
  * The MIME type of this resource, if known.
1110
1117
  */
1111
1118
  mimeType: z.optional(z.string()),
1119
+ /**
1120
+ * The size of the raw resource content, in bytes (i.e., before base64 encoding or any tokenization), if known.
1121
+ *
1122
+ * This can be used by Hosts to display file sizes and estimate context window usage.
1123
+ */
1124
+ size: z.optional(z.number()),
1112
1125
  /**
1113
1126
  * Optional annotations for the client.
1114
1127
  */
@@ -2369,7 +2382,7 @@ var coreHandler = (app) => {
2369
2382
  };
2370
2383
 
2371
2384
  // __mcpc__cli_latest/node_modules/@hono/node-server/dist/index.mjs
2372
- import { Http2ServerRequest as Http2ServerRequest2 } from "http2";
2385
+ import { Http2ServerRequest as Http2ServerRequest2, constants as h2constants } from "http2";
2373
2386
  import { Http2ServerRequest } from "http2";
2374
2387
  import { Readable } from "stream";
2375
2388
  import crypto2 from "crypto";
@@ -2583,15 +2596,17 @@ var Response2 = class _Response {
2583
2596
  this.#init = init;
2584
2597
  }
2585
2598
  if (typeof body === "string" || typeof body?.getReader !== "undefined" || body instanceof Blob || body instanceof Uint8Array) {
2586
- headers ||= init?.headers || { "content-type": "text/plain; charset=UTF-8" };
2587
- this[cacheKey] = [init?.status || 200, body, headers];
2599
+ ;
2600
+ this[cacheKey] = [init?.status || 200, body, headers || init?.headers];
2588
2601
  }
2589
2602
  }
2590
2603
  get headers() {
2591
2604
  const cache = this[cacheKey];
2592
2605
  if (cache) {
2593
2606
  if (!(cache[2] instanceof Headers)) {
2594
- cache[2] = new Headers(cache[2]);
2607
+ cache[2] = new Headers(
2608
+ cache[2] || { "content-type": "text/plain; charset=UTF-8" }
2609
+ );
2595
2610
  }
2596
2611
  return cache[2];
2597
2612
  }
@@ -2690,6 +2705,50 @@ if (typeof global.crypto === "undefined") {
2690
2705
  global.crypto = crypto2;
2691
2706
  }
2692
2707
  var outgoingEnded = Symbol("outgoingEnded");
2708
+ var incomingDraining = Symbol("incomingDraining");
2709
+ var DRAIN_TIMEOUT_MS = 500;
2710
+ var MAX_DRAIN_BYTES = 64 * 1024 * 1024;
2711
+ var drainIncoming = (incoming) => {
2712
+ const incomingWithDrainState = incoming;
2713
+ if (incoming.destroyed || incomingWithDrainState[incomingDraining]) {
2714
+ return;
2715
+ }
2716
+ incomingWithDrainState[incomingDraining] = true;
2717
+ if (incoming instanceof Http2ServerRequest2) {
2718
+ try {
2719
+ ;
2720
+ incoming.stream?.close?.(h2constants.NGHTTP2_NO_ERROR);
2721
+ } catch {
2722
+ }
2723
+ return;
2724
+ }
2725
+ let bytesRead = 0;
2726
+ const cleanup = () => {
2727
+ clearTimeout(timer);
2728
+ incoming.off("data", onData);
2729
+ incoming.off("end", cleanup);
2730
+ incoming.off("error", cleanup);
2731
+ };
2732
+ const forceClose = () => {
2733
+ cleanup();
2734
+ const socket = incoming.socket;
2735
+ if (socket && !socket.destroyed) {
2736
+ socket.destroySoon();
2737
+ }
2738
+ };
2739
+ const timer = setTimeout(forceClose, DRAIN_TIMEOUT_MS);
2740
+ timer.unref?.();
2741
+ const onData = (chunk) => {
2742
+ bytesRead += chunk.length;
2743
+ if (bytesRead > MAX_DRAIN_BYTES) {
2744
+ forceClose();
2745
+ }
2746
+ };
2747
+ incoming.on("data", onData);
2748
+ incoming.on("end", cleanup);
2749
+ incoming.on("error", cleanup);
2750
+ incoming.resume();
2751
+ };
2693
2752
  var handleRequestError = () => new Response(null, {
2694
2753
  status: 400
2695
2754
  });
@@ -2716,15 +2775,32 @@ var flushHeaders = (outgoing) => {
2716
2775
  };
2717
2776
  var responseViaCache = async (res, outgoing) => {
2718
2777
  let [status, body, header] = res[cacheKey];
2719
- if (header instanceof Headers) {
2778
+ let hasContentLength = false;
2779
+ if (!header) {
2780
+ header = { "content-type": "text/plain; charset=UTF-8" };
2781
+ } else if (header instanceof Headers) {
2782
+ hasContentLength = header.has("content-length");
2720
2783
  header = buildOutgoingHttpHeaders(header);
2784
+ } else if (Array.isArray(header)) {
2785
+ const headerObj = new Headers(header);
2786
+ hasContentLength = headerObj.has("content-length");
2787
+ header = buildOutgoingHttpHeaders(headerObj);
2788
+ } else {
2789
+ for (const key in header) {
2790
+ if (key.length === 14 && key.toLowerCase() === "content-length") {
2791
+ hasContentLength = true;
2792
+ break;
2793
+ }
2794
+ }
2721
2795
  }
2722
- if (typeof body === "string") {
2723
- header["Content-Length"] = Buffer.byteLength(body);
2724
- } else if (body instanceof Uint8Array) {
2725
- header["Content-Length"] = body.byteLength;
2726
- } else if (body instanceof Blob) {
2727
- header["Content-Length"] = body.size;
2796
+ if (!hasContentLength) {
2797
+ if (typeof body === "string") {
2798
+ header["Content-Length"] = Buffer.byteLength(body);
2799
+ } else if (body instanceof Uint8Array) {
2800
+ header["Content-Length"] = body.byteLength;
2801
+ } else if (body instanceof Blob) {
2802
+ header["Content-Length"] = body.size;
2803
+ }
2728
2804
  }
2729
2805
  outgoing.writeHead(status, header);
2730
2806
  if (typeof body === "string" || body instanceof Uint8Array) {
@@ -2844,14 +2920,18 @@ var getRequestListener = (fetchCallback, options = {}) => {
2844
2920
  setTimeout(() => {
2845
2921
  if (!incomingEnded) {
2846
2922
  setTimeout(() => {
2847
- incoming.destroy();
2848
- outgoing.destroy();
2923
+ drainIncoming(incoming);
2849
2924
  });
2850
2925
  }
2851
2926
  });
2852
2927
  }
2853
2928
  };
2854
2929
  }
2930
+ outgoing.on("finish", () => {
2931
+ if (!incomingEnded) {
2932
+ drainIncoming(incoming);
2933
+ }
2934
+ });
2855
2935
  }
2856
2936
  outgoing.on("close", () => {
2857
2937
  const abortController = req[abortControllerKey];
@@ -2866,7 +2946,7 @@ var getRequestListener = (fetchCallback, options = {}) => {
2866
2946
  setTimeout(() => {
2867
2947
  if (!incomingEnded) {
2868
2948
  setTimeout(() => {
2869
- incoming.destroy();
2949
+ drainIncoming(incoming);
2870
2950
  });
2871
2951
  }
2872
2952
  });
@@ -6706,7 +6786,7 @@ function getDefaultAgents() {
6706
6786
  }
6707
6787
 
6708
6788
  // __mcpc__cli_latest/node_modules/@mcpc/cli/src/config/loader.js
6709
- var CLI_VERSION = "0.1.52";
6789
+ var CLI_VERSION = "0.1.54";
6710
6790
  function extractServerName(command, commandArgs) {
6711
6791
  for (const arg of commandArgs) {
6712
6792
  if (!arg.startsWith("-")) {
@@ -7129,7 +7209,7 @@ function applyModeOverride(config, mode) {
7129
7209
  agent.options.mode = mode;
7130
7210
  if (mode === "ai_acp" && !agent.options.acpSettings) {
7131
7211
  agent.options.acpSettings = {
7132
- command: "claude-code-acp",
7212
+ command: "claude-agent-acp",
7133
7213
  args: [],
7134
7214
  session: {}
7135
7215
  };
@@ -7550,6 +7630,10 @@ var Protocol = class {
7550
7630
  this._progressHandlers.clear();
7551
7631
  this._taskProgressTokens.clear();
7552
7632
  this._pendingDebouncedNotifications.clear();
7633
+ for (const info of this._timeoutInfo.values()) {
7634
+ clearTimeout(info.timeoutId);
7635
+ }
7636
+ this._timeoutInfo.clear();
7553
7637
  for (const controller of this._requestHandlerAbortControllers.values()) {
7554
7638
  controller.abort();
7555
7639
  }
@@ -7680,7 +7764,9 @@ var Protocol = class {
7680
7764
  await capturedTransport?.send(errorResponse);
7681
7765
  }
7682
7766
  }).catch((error) => this._onerror(new Error(`Failed to send response: ${error}`))).finally(() => {
7683
- this._requestHandlerAbortControllers.delete(request.id);
7767
+ if (this._requestHandlerAbortControllers.get(request.id) === abortController) {
7768
+ this._requestHandlerAbortControllers.delete(request.id);
7769
+ }
7684
7770
  });
7685
7771
  }
7686
7772
  _onprogress(notification) {
@@ -9804,7 +9890,7 @@ var StdioClientTransport = class {
9804
9890
  },
9805
9891
  stdio: ["pipe", "pipe", this._serverParams.stderr ?? "inherit"],
9806
9892
  shell: false,
9807
- windowsHide: process6.platform === "win32" && isElectron(),
9893
+ windowsHide: process6.platform === "win32",
9808
9894
  cwd: this._serverParams.cwd
9809
9895
  });
9810
9896
  this._process.on("error", (error) => {
@@ -9911,9 +9997,6 @@ var StdioClientTransport = class {
9911
9997
  });
9912
9998
  }
9913
9999
  };
9914
- function isElectron() {
9915
- return "type" in process6;
9916
- }
9917
10000
 
9918
10001
  // __mcpc__cli_latest/node_modules/eventsource-parser/dist/index.js
9919
10002
  var ParseError = class extends Error {
@@ -10658,12 +10741,12 @@ var AUTHORIZATION_CODE_RESPONSE_TYPE = "code";
10658
10741
  var AUTHORIZATION_CODE_CHALLENGE_METHOD = "S256";
10659
10742
  function selectClientAuthMethod(clientInformation, supportedMethods) {
10660
10743
  const hasClientSecret = clientInformation.client_secret !== void 0;
10661
- if (supportedMethods.length === 0) {
10662
- return hasClientSecret ? "client_secret_post" : "none";
10663
- }
10664
- if ("token_endpoint_auth_method" in clientInformation && clientInformation.token_endpoint_auth_method && isClientAuthMethod(clientInformation.token_endpoint_auth_method) && supportedMethods.includes(clientInformation.token_endpoint_auth_method)) {
10744
+ if ("token_endpoint_auth_method" in clientInformation && clientInformation.token_endpoint_auth_method && isClientAuthMethod(clientInformation.token_endpoint_auth_method) && (supportedMethods.length === 0 || supportedMethods.includes(clientInformation.token_endpoint_auth_method))) {
10665
10745
  return clientInformation.token_endpoint_auth_method;
10666
10746
  }
10747
+ if (supportedMethods.length === 0) {
10748
+ return hasClientSecret ? "client_secret_basic" : "none";
10749
+ }
10667
10750
  if (hasClientSecret && supportedMethods.includes("client_secret_basic")) {
10668
10751
  return "client_secret_basic";
10669
10752
  }
@@ -10774,6 +10857,7 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
10774
10857
  });
10775
10858
  }
10776
10859
  const resource = await selectResourceURL(serverUrl, provider, resourceMetadata);
10860
+ const resolvedScope = scope || resourceMetadata?.scopes_supported?.join(" ") || provider.clientMetadata.scope;
10777
10861
  let clientInformation = await Promise.resolve(provider.clientInformation());
10778
10862
  if (!clientInformation) {
10779
10863
  if (authorizationCode !== void 0) {
@@ -10797,6 +10881,7 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
10797
10881
  const fullInformation = await registerClient(authorizationServerUrl, {
10798
10882
  metadata,
10799
10883
  clientMetadata: provider.clientMetadata,
10884
+ scope: resolvedScope,
10800
10885
  fetchFn
10801
10886
  });
10802
10887
  await provider.saveClientInformation(fullInformation);
@@ -10840,7 +10925,7 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
10840
10925
  clientInformation,
10841
10926
  state,
10842
10927
  redirectUrl: provider.redirectUrl,
10843
- scope: scope || resourceMetadata?.scopes_supported?.join(" ") || provider.clientMetadata.scope,
10928
+ scope: resolvedScope,
10844
10929
  resource
10845
10930
  });
10846
10931
  await provider.saveCodeVerifier(codeVerifier);
@@ -11158,7 +11243,7 @@ async function fetchToken(provider, authorizationServerUrl, { metadata, resource
11158
11243
  fetchFn
11159
11244
  });
11160
11245
  }
11161
- async function registerClient(authorizationServerUrl, { metadata, clientMetadata, fetchFn }) {
11246
+ async function registerClient(authorizationServerUrl, { metadata, clientMetadata, scope, fetchFn }) {
11162
11247
  let registrationUrl;
11163
11248
  if (metadata) {
11164
11249
  if (!metadata.registration_endpoint) {
@@ -11173,7 +11258,10 @@ async function registerClient(authorizationServerUrl, { metadata, clientMetadata
11173
11258
  headers: {
11174
11259
  "Content-Type": "application/json"
11175
11260
  },
11176
- body: JSON.stringify(clientMetadata)
11261
+ body: JSON.stringify({
11262
+ ...clientMetadata,
11263
+ ...scope !== void 0 ? { scope } : {}
11264
+ })
11177
11265
  });
11178
11266
  if (!response.ok) {
11179
11267
  throw await parseErrorResponse(response);
@@ -12268,7 +12356,7 @@ var SystemPrompts = {
12268
12356
  </rules>
12269
12357
 
12270
12358
  <format>
12271
- Get tool schemas: \`{ "tool": "man", "args": { "tools": ["tool1", "tool2"] } }\`
12359
+ Get tool definitions: \`{ "tool": "man", "args": { "tools": ["tool1", "tool2"] } }\`
12272
12360
  Execute a tool: \`{ "tool": "tool_name", "args": { /* parameters */ } }\`
12273
12361
  </format>`,
12274
12362
  /**
@@ -12393,7 +12481,7 @@ function createArgsDefFactory(_name, _allToolNames, _depGroups, _predefinedSteps
12393
12481
  *
12394
12482
  * Only two fields:
12395
12483
  * - `tool`: which tool to execute (enum includes "man" + all tool names)
12396
- * - `args`: object with parameters. For "man": { tools: ["a", "b"] }. For others: tool parameters.
12484
+ * - `args`: object with parameters. For "man": { tools: ["a", "b"] } to fetch tool definitions (including input/output schemas). For others: tool parameters.
12397
12485
  */
12398
12486
  forAgentic: function(allToolNames) {
12399
12487
  const toolEnum = [
@@ -14344,11 +14432,12 @@ var ToolManager = class {
14344
14432
  /**
14345
14433
  * Register a tool in the registry
14346
14434
  */
14347
- registerTool(name, description, schema, callback, options = {}) {
14435
+ registerTool(name, description, inputSchema, callback, options = {}) {
14348
14436
  this.toolRegistry.set(name, {
14349
14437
  callback,
14350
14438
  description,
14351
- schema
14439
+ inputSchema,
14440
+ outputSchema: options.outputSchema
14352
14441
  });
14353
14442
  if (options.hidden) {
14354
14443
  this.toolConfigs.set(name, {
@@ -14361,13 +14450,16 @@ var ToolManager = class {
14361
14450
  /**
14362
14451
  * Explicitly mark a tool as public (exposed to MCP clients)
14363
14452
  */
14364
- addPublicTool(name, description, schema) {
14453
+ addPublicTool(name, description, inputSchema, outputSchema) {
14365
14454
  const existingTool = this.publicTools.find((t) => t.name === name);
14366
14455
  if (!existingTool) {
14367
14456
  this.publicTools.push({
14368
14457
  name,
14369
14458
  description,
14370
- inputSchema: schema
14459
+ inputSchema,
14460
+ ...outputSchema ? {
14461
+ outputSchema
14462
+ } : {}
14371
14463
  });
14372
14464
  }
14373
14465
  this.toolConfigs.set(name, {
@@ -14493,10 +14585,13 @@ var ToolManager = class {
14493
14585
  getHiddenToolSchema(name) {
14494
14586
  const tool2 = this.toolRegistry.get(name);
14495
14587
  const config = this.toolConfigs.get(name);
14496
- if (tool2 && config?.visibility?.hidden && tool2.schema) {
14588
+ if (tool2 && config?.visibility?.hidden && tool2.inputSchema) {
14497
14589
  return {
14498
14590
  description: tool2.description,
14499
- schema: tool2.schema
14591
+ inputSchema: tool2.inputSchema,
14592
+ ...tool2.outputSchema ? {
14593
+ outputSchema: tool2.outputSchema
14594
+ } : {}
14500
14595
  };
14501
14596
  }
14502
14597
  return void 0;
@@ -14532,10 +14627,13 @@ var ToolManager = class {
14532
14627
  composedTools[name] = {
14533
14628
  name,
14534
14629
  description: tool2.description,
14535
- inputSchema: jsonSchema(tool2.schema || {
14630
+ inputSchema: jsonSchema(tool2.inputSchema || {
14536
14631
  type: "object",
14537
14632
  properties: {}
14538
14633
  }),
14634
+ ...tool2.outputSchema ? {
14635
+ outputSchema: jsonSchema(tool2.outputSchema)
14636
+ } : {},
14539
14637
  execute: tool2.callback
14540
14638
  };
14541
14639
  }
@@ -14552,10 +14650,13 @@ var ToolManager = class {
14552
14650
  return {
14553
14651
  name,
14554
14652
  description: tool2.description,
14555
- inputSchema: tool2.schema ?? {
14653
+ inputSchema: tool2.inputSchema ?? {
14556
14654
  type: "object",
14557
14655
  properties: {}
14558
14656
  },
14657
+ ...tool2.outputSchema ? {
14658
+ outputSchema: tool2.outputSchema
14659
+ } : {},
14559
14660
  execute: tool2.callback
14560
14661
  };
14561
14662
  }
@@ -14569,10 +14670,13 @@ var ToolManager = class {
14569
14670
  composedTools.push({
14570
14671
  name,
14571
14672
  description: tool2.description,
14572
- inputSchema: tool2.schema ?? {
14673
+ inputSchema: tool2.inputSchema ?? {
14573
14674
  type: "object",
14574
14675
  properties: {}
14575
14676
  },
14677
+ ...tool2.outputSchema ? {
14678
+ outputSchema: tool2.outputSchema
14679
+ } : {},
14576
14680
  execute: tool2.callback
14577
14681
  });
14578
14682
  }
@@ -14625,7 +14729,10 @@ async function processToolsWithPlugins(server, _externalTools, mode) {
14625
14729
  const tempTool = {
14626
14730
  name: toolId,
14627
14731
  description: toolData.description,
14628
- inputSchema: toolData.schema || defaultSchema,
14732
+ inputSchema: toolData.inputSchema || defaultSchema,
14733
+ ...toolData.outputSchema ? {
14734
+ outputSchema: toolData.outputSchema
14735
+ } : {},
14629
14736
  execute: toolData.callback
14630
14737
  };
14631
14738
  const processedTool = await pluginManager.applyTransformToolHooks(tempTool, {
@@ -14637,7 +14744,9 @@ async function processToolsWithPlugins(server, _externalTools, mode) {
14637
14744
  },
14638
14745
  transformationIndex: 0
14639
14746
  });
14640
- toolManager.registerTool(toolId, processedTool.description || toolData.description, processedTool.inputSchema, processedTool.execute);
14747
+ toolManager.registerTool(toolId, processedTool.description || toolData.description, processedTool.inputSchema, processedTool.execute, {
14748
+ outputSchema: processedTool.outputSchema
14749
+ });
14641
14750
  }
14642
14751
  }
14643
14752
  function buildDependencyGroups(toolNameToDetailList, hiddenToolNames, publicToolNames, server) {
@@ -14683,6 +14792,7 @@ var ComposableMCPServer = class extends Server {
14683
14792
  toolManager;
14684
14793
  logger = createLogger("mcpc.compose");
14685
14794
  fileLoaders = /* @__PURE__ */ new Map();
14795
+ pluginsDisposed = false;
14686
14796
  // Legacy property for backward compatibility
14687
14797
  get toolNameMapping() {
14688
14798
  return this.toolManager.getToolNameMapping();
@@ -14811,9 +14921,13 @@ var ComposableMCPServer = class extends Server {
14811
14921
  }
14812
14922
  tool(name, description, paramsSchema, cb, options = {}) {
14813
14923
  const jsonSchemaObj = extractJsonSchema(paramsSchema);
14814
- this.toolManager.registerTool(name, description, jsonSchemaObj, cb, options);
14924
+ const outputSchemaObj = options.outputSchema ? extractJsonSchema(options.outputSchema) : void 0;
14925
+ this.toolManager.registerTool(name, description, jsonSchemaObj, cb, {
14926
+ ...options,
14927
+ outputSchema: outputSchemaObj
14928
+ });
14815
14929
  if (!options.internal) {
14816
- this.toolManager.addPublicTool(name, description, jsonSchemaObj);
14930
+ this.toolManager.addPublicTool(name, description, jsonSchemaObj, outputSchemaObj);
14817
14931
  }
14818
14932
  if (options.plugins) {
14819
14933
  for (const plugin of options.plugins) {
@@ -15070,9 +15184,12 @@ var ComposableMCPServer = class extends Server {
15070
15184
  return {
15071
15185
  name,
15072
15186
  description: tool2?.description || "",
15073
- inputSchema: tool2?.schema || {
15187
+ inputSchema: tool2?.inputSchema || {
15074
15188
  type: "object"
15075
- }
15189
+ },
15190
+ ...tool2?.outputSchema ? {
15191
+ outputSchema: tool2.outputSchema
15192
+ } : {}
15076
15193
  };
15077
15194
  });
15078
15195
  }
@@ -15097,9 +15214,12 @@ var ComposableMCPServer = class extends Server {
15097
15214
  return Array.from(registry.entries()).map(([name, tool2]) => ({
15098
15215
  name,
15099
15216
  description: tool2?.description || "",
15100
- inputSchema: tool2?.schema || {
15217
+ inputSchema: tool2?.inputSchema || {
15101
15218
  type: "object"
15102
- }
15219
+ },
15220
+ ...tool2?.outputSchema ? {
15221
+ outputSchema: tool2.outputSchema
15222
+ } : {}
15103
15223
  }));
15104
15224
  }
15105
15225
  /**
@@ -15158,11 +15278,21 @@ var ComposableMCPServer = class extends Server {
15158
15278
  async disposePlugins() {
15159
15279
  await this.pluginManager.dispose();
15160
15280
  }
15281
+ /**
15282
+ * Dispose plugins only once to avoid duplicated cleanup in chained handlers.
15283
+ */
15284
+ async disposePluginsOnce() {
15285
+ if (this.pluginsDisposed) {
15286
+ return;
15287
+ }
15288
+ this.pluginsDisposed = true;
15289
+ await this.disposePlugins();
15290
+ }
15161
15291
  /**
15162
15292
  * Close the server and ensure all plugins are disposed
15163
15293
  */
15164
15294
  async close() {
15165
- await this.disposePlugins();
15295
+ await this.disposePluginsOnce();
15166
15296
  await super.close();
15167
15297
  }
15168
15298
  async compose(name, description, depsConfig = {
@@ -15231,7 +15361,9 @@ var ComposableMCPServer = class extends Server {
15231
15361
  });
15232
15362
  });
15233
15363
  Object.entries(tools).forEach(([toolId, tool2]) => {
15234
- this.toolManager.registerTool(toolId, tool2.description || "", tool2.inputSchema, tool2.execute);
15364
+ this.toolManager.registerTool(toolId, tool2.description || "", tool2.inputSchema, tool2.execute, {
15365
+ outputSchema: tool2.outputSchema
15366
+ });
15235
15367
  });
15236
15368
  const registeredTools = this.toolManager.getRegisteredToolsAsComposed();
15237
15369
  const allTools = {
@@ -15267,16 +15399,20 @@ var ComposableMCPServer = class extends Server {
15267
15399
  server: this,
15268
15400
  toolNames: Object.keys(allTools)
15269
15401
  });
15402
+ const previousOnClose = this.onclose;
15270
15403
  this.onclose = async () => {
15271
15404
  await cleanupClients();
15272
- await this.disposePlugins();
15405
+ await this.disposePluginsOnce();
15273
15406
  await this.logger.info(`[${name}] Event: closed - cleaned up dependent clients and plugins`);
15407
+ previousOnClose?.();
15274
15408
  };
15409
+ const previousOnError = this.onerror;
15275
15410
  this.onerror = async (error) => {
15276
15411
  await this.logger.error(`[${name}] Event: error - ${error?.stack ?? String(error)}`);
15277
15412
  await cleanupClients();
15278
- await this.disposePlugins();
15413
+ await this.disposePluginsOnce();
15279
15414
  await this.logger.info(`[${name}] Action: cleaned up dependent clients and plugins`);
15415
+ previousOnError?.(error);
15280
15416
  };
15281
15417
  const toolNameToDetailList = Object.entries(allTools);
15282
15418
  const publicToolNames = this.getPublicToolNames();
@@ -15288,7 +15424,8 @@ var ComposableMCPServer = class extends Server {
15288
15424
  return;
15289
15425
  }
15290
15426
  this.tool(toolId, tool2.description || "", jsonSchema(tool2.inputSchema), tool2.execute, {
15291
- internal: false
15427
+ internal: false,
15428
+ outputSchema: tool2.outputSchema
15292
15429
  });
15293
15430
  });
15294
15431
  await this.pluginManager.triggerComposeEnd({