@mcpc-tech/unplugin-dev-inspector-mcp 0.0.38 → 0.0.40

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.
@@ -37,6 +37,7 @@ let url = require("url");
37
37
  let ai = require("ai");
38
38
  let _agentclientprotocol_sdk = require("@agentclientprotocol/sdk");
39
39
  let node_child_process = require("node:child_process");
40
+ let module$1 = require("module");
40
41
  let fs_promises = require("fs/promises");
41
42
 
42
43
  //#region ../../node_modules/.pnpm/@mcpc-tech+cmcp@0.0.15/node_modules/@mcpc-tech/cmcp/index.mjs
@@ -34870,7 +34871,7 @@ var require_snapshot_utils = /* @__PURE__ */ require_chunk.__commonJSMin(((expor
34870
34871
  //#region ../../node_modules/.pnpm/undici@7.16.0/node_modules/undici/lib/mock/snapshot-recorder.js
34871
34872
  var require_snapshot_recorder = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
34872
34873
  const { writeFile: writeFile$1, readFile: readFile$1, mkdir: mkdir$1 } = require("node:fs/promises");
34873
- const { dirname: dirname$1, resolve } = require("node:path");
34874
+ const { dirname: dirname$2, resolve } = require("node:path");
34874
34875
  const { setTimeout: setTimeout$1, clearTimeout: clearTimeout$1 } = require("node:timers");
34875
34876
  const { InvalidArgumentError, UndiciError } = require_errors$1();
34876
34877
  const { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require_snapshot_utils();
@@ -35149,7 +35150,7 @@ var require_snapshot_recorder = /* @__PURE__ */ require_chunk.__commonJSMin(((ex
35149
35150
  const path$3 = filePath || this.#snapshotPath;
35150
35151
  if (!path$3) throw new InvalidArgumentError("Snapshot path is required");
35151
35152
  const resolvedPath = resolve(path$3);
35152
- await mkdir$1(dirname$1(resolvedPath), { recursive: true });
35153
+ await mkdir$1(dirname$2(resolvedPath), { recursive: true });
35153
35154
  const data$1 = Array.from(this.#snapshots.entries()).map(([hash, snapshot]) => ({
35154
35155
  hash,
35155
35156
  snapshot
@@ -83446,6 +83447,19 @@ async function getOrCreateMcpClient(defKey, def) {
83446
83447
  mcpClientConnecting.delete(defKey);
83447
83448
  }
83448
83449
  }
83450
+ async function releaseMcpClient(defKey) {
83451
+ const entry = mcpClientPool.get(defKey);
83452
+ if (!entry) return;
83453
+ entry.refCount -= 1;
83454
+ if (entry.refCount <= 0) {
83455
+ mcpClientPool.delete(defKey);
83456
+ try {
83457
+ await entry.client.close();
83458
+ } catch (err) {
83459
+ console.error("Error closing MCP client:", err);
83460
+ }
83461
+ }
83462
+ }
83449
83463
  var cleanupAllPooledClients = async () => {
83450
83464
  const entries = Array.from(mcpClientPool.entries());
83451
83465
  mcpClientPool.clear();
@@ -83503,7 +83517,12 @@ async function composeMcpDepTools(mcpConfig, filterIn) {
83503
83517
  console.error(`Error creating MCP client for ${name}:`, error);
83504
83518
  }
83505
83519
  }
83506
- const cleanupClients = async () => {};
83520
+ const cleanupClients = async () => {
83521
+ await Promise.all(acquiredKeys.map((k) => releaseMcpClient(k)));
83522
+ acquiredKeys.length = 0;
83523
+ Object.keys(allTools).forEach((key) => delete allTools[key]);
83524
+ Object.keys(allClients).forEach((key) => delete allClients[key]);
83525
+ };
83507
83526
  return {
83508
83527
  tools: allTools,
83509
83528
  clients: allClients,
@@ -86305,6 +86324,17 @@ var ComposableMCPServer = class extends _modelcontextprotocol_sdk_server_index_j
86305
86324
  server: this,
86306
86325
  toolNames: Object.keys(allTools)
86307
86326
  });
86327
+ this.onclose = async () => {
86328
+ await cleanupClients();
86329
+ await this.disposePlugins();
86330
+ await this.logger.info(`[${name}] Event: closed - cleaned up dependent clients and plugins`);
86331
+ };
86332
+ this.onerror = async (error) => {
86333
+ await this.logger.error(`[${name}] Event: error - ${error?.stack ?? String(error)}`);
86334
+ await cleanupClients();
86335
+ await this.disposePlugins();
86336
+ await this.logger.info(`[${name}] Action: cleaned up dependent clients and plugins`);
86337
+ };
86308
86338
  const toolNameToDetailList = Object.entries(allTools);
86309
86339
  const publicToolNames = this.getPublicToolNames();
86310
86340
  const hiddenToolNames = this.getHiddenToolNames();
@@ -86896,14 +86926,20 @@ var ConnectionManager = class {
86896
86926
  //#endregion
86897
86927
  //#region src/utils/cors.ts
86898
86928
  /**
86899
- * Set CORS headers and handle preflight requests
86900
- * Returns true if request was handled (preflight), false otherwise
86929
+ * Set CORS headers and handle preflight requests.
86930
+ *
86931
+ * Uses the browser's requested headers (Access-Control-Request-Headers) when present
86932
+ * to avoid mismatches that can break CORS preflight (e.g. 'user-agent').
86933
+ *
86934
+ * Returns true if request was handled (preflight), false otherwise.
86901
86935
  */
86902
- function handleCors(res, method) {
86936
+ function handleCors(req, res) {
86903
86937
  res.setHeader("Access-Control-Allow-Origin", "*");
86904
86938
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
86905
- res.setHeader("Access-Control-Allow-Headers", "Content-Type, mcp-session-id, mcp-protocol-version");
86906
- if (method === "OPTIONS") {
86939
+ const requested = req.headers["access-control-request-headers"];
86940
+ const requestedValue = Array.isArray(requested) ? requested.join(", ") : requested;
86941
+ res.setHeader("Access-Control-Allow-Headers", requestedValue ?? "Content-Type, mcp-session-id, mcp-protocol-version");
86942
+ if (req.method === "OPTIONS") {
86907
86943
  res.statusCode = 204;
86908
86944
  res.end();
86909
86945
  return true;
@@ -86929,7 +86965,7 @@ async function setupMcpMiddleware(middlewares, serverContext) {
86929
86965
  middlewares.use(async (req, res, next$1) => {
86930
86966
  const url$1 = req.url || "";
86931
86967
  if (url$1.startsWith("/__mcp__")) {
86932
- if (handleCors(res, req.method)) return;
86968
+ if (handleCors(req, res)) return;
86933
86969
  }
86934
86970
  if (url$1.startsWith("/__mcp__") && !url$1.startsWith("/__mcp__/sse") && !url$1.startsWith("/__mcp__/messages")) {
86935
86971
  if (req.method === "POST") await handleStreamableHttpPost(req, res, serverContext, connectionManager);
@@ -87166,7 +87202,7 @@ function setupInspectorMiddleware(middlewares, config) {
87166
87202
  let filesChecked = false;
87167
87203
  middlewares.use((req, res, next$1) => {
87168
87204
  if (req.url?.startsWith("/__inspector__")) {
87169
- if (handleCors(res, req.method)) return;
87205
+ if (handleCors(req, res)) return;
87170
87206
  }
87171
87207
  if (!filesChecked) {
87172
87208
  cachedScript = getInspectorScript();
@@ -87209,7 +87245,7 @@ function setupInspectorMiddleware(middlewares, config) {
87209
87245
  }
87210
87246
 
87211
87247
  //#endregion
87212
- //#region ../../node_modules/.pnpm/@mcpc-tech+acp-ai-provider@0.1.41/node_modules/@mcpc-tech/acp-ai-provider/index.mjs
87248
+ //#region ../../node_modules/.pnpm/@mcpc-tech+acp-ai-provider@0.1.43/node_modules/@mcpc-tech/acp-ai-provider/index.mjs
87213
87249
  (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
87214
87250
  function formatToolError(toolResult) {
87215
87251
  if (!toolResult || toolResult.length === 0) return "Unknown tool error";
@@ -87652,7 +87688,6 @@ var ACPLanguageModel = class {
87652
87688
  */
87653
87689
  parseToolCall(update$1) {
87654
87690
  if (update$1.sessionUpdate !== "tool_call") throw new Error("Invalid update type for parseToolCall");
87655
- console.log("Parsing tool call update:", JSON.stringify(update$1, null, 2));
87656
87691
  return {
87657
87692
  toolCallId: update$1.toolCallId,
87658
87693
  toolName: update$1.title || update$1.toolCallId,
@@ -87954,11 +87989,6 @@ var ACPLanguageModel = class {
87954
87989
  this.currentThinkingId = null;
87955
87990
  }
87956
87991
  const { toolCallId, toolName, toolInput } = this.parseToolCall(update$1);
87957
- console.log(`Parsing tool call: ${JSON.stringify({
87958
- toolCallId,
87959
- toolName,
87960
- toolInput
87961
- }, null, 2)}`);
87962
87992
  const existingToolCall = this.toolCallsMap.get(toolCallId);
87963
87993
  const hasInput = toolInput && typeof toolInput === "object" && Object.keys(toolInput).length > 0;
87964
87994
  if (!existingToolCall) {
@@ -87985,13 +88015,14 @@ var ACPLanguageModel = class {
87985
88015
  });
87986
88016
  } else if (!existingToolCall.inputAvailable && hasInput) {
87987
88017
  existingToolCall.inputAvailable = true;
88018
+ if (update$1.title && existingToolCall.name !== update$1.title && update$1.title !== toolCallId) existingToolCall.name = update$1.title;
87988
88019
  controller.enqueue({
87989
88020
  type: "tool-call",
87990
88021
  toolCallId,
87991
88022
  toolName: ACP_PROVIDER_AGENT_DYNAMIC_TOOL_NAME2,
87992
88023
  input: JSON.stringify({
87993
88024
  toolCallId,
87994
- toolName,
88025
+ toolName: existingToolCall.name,
87995
88026
  args: toolInput
87996
88027
  })
87997
88028
  });
@@ -88018,13 +88049,14 @@ var ACPLanguageModel = class {
88018
88049
  }
88019
88050
  if (!toolInfo.inputAvailable) {
88020
88051
  toolInfo.inputAvailable = true;
88052
+ if (update$1.title && toolInfo.name !== update$1.title && update$1.title !== toolCallId) toolInfo.name = update$1.title;
88021
88053
  controller.enqueue({
88022
88054
  type: "tool-call",
88023
88055
  toolCallId,
88024
88056
  toolName: ACP_PROVIDER_AGENT_DYNAMIC_TOOL_NAME2,
88025
88057
  input: JSON.stringify({
88026
88058
  toolCallId,
88027
- toolName,
88059
+ toolName: toolInfo.name,
88028
88060
  args: {}
88029
88061
  })
88030
88062
  });
@@ -88050,13 +88082,14 @@ var ACPLanguageModel = class {
88050
88082
  });
88051
88083
  } else if (!toolInfo.inputAvailable) {
88052
88084
  toolInfo.inputAvailable = true;
88085
+ if (update$1.title && toolInfo.name !== update$1.title && update$1.title !== toolCallId) toolInfo.name = update$1.title;
88053
88086
  controller.enqueue({
88054
88087
  type: "tool-call",
88055
88088
  toolCallId,
88056
88089
  toolName: ACP_PROVIDER_AGENT_DYNAMIC_TOOL_NAME2,
88057
88090
  input: JSON.stringify({
88058
88091
  toolCallId,
88059
- toolName,
88092
+ toolName: toolInfo.name,
88060
88093
  args: {}
88061
88094
  })
88062
88095
  });
@@ -88083,7 +88116,6 @@ var ACPLanguageModel = class {
88083
88116
  try {
88084
88117
  await this.ensureConnected();
88085
88118
  const promptContent = convertAiSdkMessagesToAcp(options, this.isFreshSession);
88086
- console.log(`###########`, promptContent);
88087
88119
  this.isFreshSession = false;
88088
88120
  let accumulatedText = "";
88089
88121
  const toolCalls = [];
@@ -88290,6 +88322,36 @@ function createACPProvider(config) {
88290
88322
  return new ACPProvider(config);
88291
88323
  }
88292
88324
 
88325
+ //#endregion
88326
+ //#region src/utils/npm-package.ts
88327
+ /**
88328
+ * Resolve npm package bin entry point
88329
+ * Returns the absolute path to the bin file, or null if resolution fails
88330
+ */
88331
+ function resolveNpmPackageBin(packageName) {
88332
+ try {
88333
+ const packageJsonPath = (0, module$1.createRequire)(require("url").pathToFileURL(__filename).href).resolve(`${packageName}/package.json`);
88334
+ const packageJson = JSON.parse((0, fs.readFileSync)(packageJsonPath, "utf-8"));
88335
+ let binPath;
88336
+ if (typeof packageJson.bin === "string") binPath = packageJson.bin;
88337
+ else if (typeof packageJson.bin === "object") {
88338
+ const binEntries = Object.entries(packageJson.bin);
88339
+ const matchingEntry = binEntries.find(([name]) => name === packageJson.name.split("/").pop());
88340
+ binPath = matchingEntry ? matchingEntry[1] : binEntries[0]?.[1];
88341
+ }
88342
+ if (!binPath) {
88343
+ console.warn(`[dev-inspector] [acp] No bin entry found in ${packageName}/package.json`);
88344
+ return null;
88345
+ }
88346
+ const binFullPath = (0, path.join)((0, path.dirname)(packageJsonPath), binPath);
88347
+ console.log(`[dev-inspector] [acp] Resolved ${packageName} bin to: ${binFullPath}`);
88348
+ return binFullPath;
88349
+ } catch (error) {
88350
+ console.warn(`[dev-inspector] [acp] Failed to resolve npm package ${packageName}:`, error);
88351
+ return null;
88352
+ }
88353
+ }
88354
+
88293
88355
  //#endregion
88294
88356
  //#region src/middleware/acp-middleware.ts
88295
88357
  /**
@@ -88358,10 +88420,13 @@ async function loadMcpToolsV5(transport) {
88358
88420
  inputSchema: (0, ai.jsonSchema)(toolInfo.inputSchema),
88359
88421
  execute: async (args) => {
88360
88422
  console.log(`[dev-inspector] [acp] Executing MCP tool: ${toolName}`);
88361
- return await callMcpMethodViaTransport(transport, "tools/call", {
88423
+ const result = await callMcpMethodViaTransport(transport, "tools/call", {
88362
88424
  name: toolName,
88363
88425
  arguments: args
88364
88426
  });
88427
+ const parsedResult = _modelcontextprotocol_sdk_types_js.CallToolResultSchema.safeParse(result);
88428
+ if (!parsedResult.success) return result;
88429
+ return parsedResult.data?.content?.map((item) => item?.text).join("\n");
88365
88430
  }
88366
88431
  });
88367
88432
  }
@@ -88405,7 +88470,7 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
88405
88470
  * Returns: { sessionId }
88406
88471
  */
88407
88472
  middlewares.use("/api/acp/init-session", async (req, res) => {
88408
- if (handleCors(res, req.method)) return;
88473
+ if (handleCors(req, res)) return;
88409
88474
  if (req.method !== "POST") {
88410
88475
  res.statusCode = 405;
88411
88476
  res.end("Method Not Allowed");
@@ -88451,9 +88516,19 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
88451
88516
  return;
88452
88517
  }
88453
88518
  console.log(`[dev-inspector] [acp] Creating new global provider for ${agent.name}`);
88519
+ let command = agent.command;
88520
+ let args = agent.args;
88521
+ if (agent.npmPackage) {
88522
+ const binPath = resolveNpmPackageBin(agent.npmPackage);
88523
+ if (binPath) {
88524
+ command = binPath;
88525
+ args = agent.npmArgs || [];
88526
+ console.log(`[dev-inspector] [acp] Using resolved npm package: ${agent.npmPackage}`);
88527
+ } else console.log(`[dev-inspector] [acp] Failed to resolve npm package, falling back to: ${agent.command}`);
88528
+ }
88454
88529
  provider = createACPProvider({
88455
- command: agent.command,
88456
- args: agent.args,
88530
+ command,
88531
+ args,
88457
88532
  env: {
88458
88533
  ...process.env,
88459
88534
  ...envVars
@@ -88522,7 +88597,7 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
88522
88597
  * Body: { sessionId }
88523
88598
  */
88524
88599
  middlewares.use("/api/acp/cleanup-session", async (req, res) => {
88525
- if (handleCors(res, req.method)) return;
88600
+ if (handleCors(req, res)) return;
88526
88601
  if (req.method !== "POST") {
88527
88602
  res.statusCode = 405;
88528
88603
  res.end("Method Not Allowed");
@@ -88565,7 +88640,7 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
88565
88640
  * Body: { messages, agent, envVars, sessionId? }
88566
88641
  */
88567
88642
  middlewares.use("/api/acp/chat", async (req, res) => {
88568
- if (handleCors(res, req.method)) return;
88643
+ if (handleCors(req, res)) return;
88569
88644
  if (req.method !== "POST") {
88570
88645
  res.statusCode = 405;
88571
88646
  res.end("Method Not Allowed");
@@ -88588,9 +88663,19 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
88588
88663
  shouldCleanupProvider = false;
88589
88664
  } else {
88590
88665
  console.log(`[dev-inspector] [acp] Creating new provider (no session found or provided)`);
88666
+ let command = agent.command;
88667
+ let args = agent.args;
88668
+ if (agent.npmPackage) {
88669
+ const binPath = resolveNpmPackageBin(agent.npmPackage);
88670
+ if (binPath) {
88671
+ command = binPath;
88672
+ args = agent.npmArgs || [];
88673
+ console.log(`[dev-inspector] [acp] Using resolved npm package: ${agent.npmPackage}`);
88674
+ }
88675
+ }
88591
88676
  provider = createACPProvider({
88592
- command: agent.command,
88593
- args: agent.args,
88677
+ command,
88678
+ args,
88594
88679
  env: {
88595
88680
  ...process.env,
88596
88681
  ...envVars
@@ -2,7 +2,7 @@ import { createRequire } from "node:module";
2
2
  import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
3
3
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
4
4
  import { randomUUID } from "crypto";
5
- import { CallToolRequestSchema, CompleteRequestSchema, ErrorCode, GetPromptRequestSchema, JSONRPCMessageSchema, ListPromptsRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, McpError, PingRequestSchema, ReadResourceRequestSchema, SetLevelRequestSchema, SubscribeRequestSchema, UnsubscribeRequestSchema } from "@modelcontextprotocol/sdk/types.js";
5
+ import { CallToolRequestSchema, CallToolResultSchema, CompleteRequestSchema, ErrorCode, GetPromptRequestSchema, JSONRPCMessageSchema, ListPromptsRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, McpError, PingRequestSchema, ReadResourceRequestSchema, SetLevelRequestSchema, SubscribeRequestSchema, UnsubscribeRequestSchema } from "@modelcontextprotocol/sdk/types.js";
6
6
  import z$1, { z } from "zod";
7
7
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
8
8
  import { Readable, Writable } from "node:stream";
@@ -18,7 +18,7 @@ import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
18
18
  import process$1, { cwd } from "node:process";
19
19
  import { homedir } from "os";
20
20
  import { execSync } from "child_process";
21
- import fs, { existsSync } from "fs";
21
+ import fs, { existsSync, readFileSync } from "fs";
22
22
  import * as http from "http";
23
23
  import * as https from "https";
24
24
  import * as zlib from "zlib";
@@ -28,6 +28,7 @@ import { fileURLToPath as fileURLToPath$1 } from "url";
28
28
  import { asSchema, convertToModelMessages, jsonSchema, streamText, tool } from "ai";
29
29
  import { ClientSideConnection, PROTOCOL_VERSION, ndJsonStream, planEntrySchema } from "@agentclientprotocol/sdk";
30
30
  import { spawn } from "node:child_process";
31
+ import { createRequire as createRequire$1 } from "module";
31
32
  import { mkdir, readFile, writeFile } from "fs/promises";
32
33
 
33
34
  //#region rolldown:runtime
@@ -83481,6 +83482,19 @@ async function getOrCreateMcpClient(defKey, def) {
83481
83482
  mcpClientConnecting.delete(defKey);
83482
83483
  }
83483
83484
  }
83485
+ async function releaseMcpClient(defKey) {
83486
+ const entry = mcpClientPool.get(defKey);
83487
+ if (!entry) return;
83488
+ entry.refCount -= 1;
83489
+ if (entry.refCount <= 0) {
83490
+ mcpClientPool.delete(defKey);
83491
+ try {
83492
+ await entry.client.close();
83493
+ } catch (err) {
83494
+ console.error("Error closing MCP client:", err);
83495
+ }
83496
+ }
83497
+ }
83484
83498
  var cleanupAllPooledClients = async () => {
83485
83499
  const entries = Array.from(mcpClientPool.entries());
83486
83500
  mcpClientPool.clear();
@@ -83538,7 +83552,12 @@ async function composeMcpDepTools(mcpConfig, filterIn) {
83538
83552
  console.error(`Error creating MCP client for ${name}:`, error);
83539
83553
  }
83540
83554
  }
83541
- const cleanupClients = async () => {};
83555
+ const cleanupClients = async () => {
83556
+ await Promise.all(acquiredKeys.map((k) => releaseMcpClient(k)));
83557
+ acquiredKeys.length = 0;
83558
+ Object.keys(allTools).forEach((key) => delete allTools[key]);
83559
+ Object.keys(allClients).forEach((key) => delete allClients[key]);
83560
+ };
83542
83561
  return {
83543
83562
  tools: allTools,
83544
83563
  clients: allClients,
@@ -86340,6 +86359,17 @@ var ComposableMCPServer = class extends Server {
86340
86359
  server: this,
86341
86360
  toolNames: Object.keys(allTools)
86342
86361
  });
86362
+ this.onclose = async () => {
86363
+ await cleanupClients();
86364
+ await this.disposePlugins();
86365
+ await this.logger.info(`[${name}] Event: closed - cleaned up dependent clients and plugins`);
86366
+ };
86367
+ this.onerror = async (error) => {
86368
+ await this.logger.error(`[${name}] Event: error - ${error?.stack ?? String(error)}`);
86369
+ await cleanupClients();
86370
+ await this.disposePlugins();
86371
+ await this.logger.info(`[${name}] Action: cleaned up dependent clients and plugins`);
86372
+ };
86343
86373
  const toolNameToDetailList = Object.entries(allTools);
86344
86374
  const publicToolNames = this.getPublicToolNames();
86345
86375
  const hiddenToolNames = this.getHiddenToolNames();
@@ -86931,14 +86961,20 @@ var ConnectionManager = class {
86931
86961
  //#endregion
86932
86962
  //#region src/utils/cors.ts
86933
86963
  /**
86934
- * Set CORS headers and handle preflight requests
86935
- * Returns true if request was handled (preflight), false otherwise
86964
+ * Set CORS headers and handle preflight requests.
86965
+ *
86966
+ * Uses the browser's requested headers (Access-Control-Request-Headers) when present
86967
+ * to avoid mismatches that can break CORS preflight (e.g. 'user-agent').
86968
+ *
86969
+ * Returns true if request was handled (preflight), false otherwise.
86936
86970
  */
86937
- function handleCors(res, method) {
86971
+ function handleCors(req, res) {
86938
86972
  res.setHeader("Access-Control-Allow-Origin", "*");
86939
86973
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
86940
- res.setHeader("Access-Control-Allow-Headers", "Content-Type, mcp-session-id, mcp-protocol-version");
86941
- if (method === "OPTIONS") {
86974
+ const requested = req.headers["access-control-request-headers"];
86975
+ const requestedValue = Array.isArray(requested) ? requested.join(", ") : requested;
86976
+ res.setHeader("Access-Control-Allow-Headers", requestedValue ?? "Content-Type, mcp-session-id, mcp-protocol-version");
86977
+ if (req.method === "OPTIONS") {
86942
86978
  res.statusCode = 204;
86943
86979
  res.end();
86944
86980
  return true;
@@ -86964,7 +87000,7 @@ async function setupMcpMiddleware(middlewares, serverContext) {
86964
87000
  middlewares.use(async (req, res, next$1) => {
86965
87001
  const url = req.url || "";
86966
87002
  if (url.startsWith("/__mcp__")) {
86967
- if (handleCors(res, req.method)) return;
87003
+ if (handleCors(req, res)) return;
86968
87004
  }
86969
87005
  if (url.startsWith("/__mcp__") && !url.startsWith("/__mcp__/sse") && !url.startsWith("/__mcp__/messages")) {
86970
87006
  if (req.method === "POST") await handleStreamableHttpPost(req, res, serverContext, connectionManager);
@@ -87201,7 +87237,7 @@ function setupInspectorMiddleware(middlewares, config) {
87201
87237
  let filesChecked = false;
87202
87238
  middlewares.use((req, res, next$1) => {
87203
87239
  if (req.url?.startsWith("/__inspector__")) {
87204
- if (handleCors(res, req.method)) return;
87240
+ if (handleCors(req, res)) return;
87205
87241
  }
87206
87242
  if (!filesChecked) {
87207
87243
  cachedScript = getInspectorScript();
@@ -87244,7 +87280,7 @@ function setupInspectorMiddleware(middlewares, config) {
87244
87280
  }
87245
87281
 
87246
87282
  //#endregion
87247
- //#region ../../node_modules/.pnpm/@mcpc-tech+acp-ai-provider@0.1.41/node_modules/@mcpc-tech/acp-ai-provider/index.mjs
87283
+ //#region ../../node_modules/.pnpm/@mcpc-tech+acp-ai-provider@0.1.43/node_modules/@mcpc-tech/acp-ai-provider/index.mjs
87248
87284
  createRequire(import.meta.url);
87249
87285
  function formatToolError(toolResult) {
87250
87286
  if (!toolResult || toolResult.length === 0) return "Unknown tool error";
@@ -87687,7 +87723,6 @@ var ACPLanguageModel = class {
87687
87723
  */
87688
87724
  parseToolCall(update$1) {
87689
87725
  if (update$1.sessionUpdate !== "tool_call") throw new Error("Invalid update type for parseToolCall");
87690
- console.log("Parsing tool call update:", JSON.stringify(update$1, null, 2));
87691
87726
  return {
87692
87727
  toolCallId: update$1.toolCallId,
87693
87728
  toolName: update$1.title || update$1.toolCallId,
@@ -87989,11 +88024,6 @@ var ACPLanguageModel = class {
87989
88024
  this.currentThinkingId = null;
87990
88025
  }
87991
88026
  const { toolCallId, toolName, toolInput } = this.parseToolCall(update$1);
87992
- console.log(`Parsing tool call: ${JSON.stringify({
87993
- toolCallId,
87994
- toolName,
87995
- toolInput
87996
- }, null, 2)}`);
87997
88027
  const existingToolCall = this.toolCallsMap.get(toolCallId);
87998
88028
  const hasInput = toolInput && typeof toolInput === "object" && Object.keys(toolInput).length > 0;
87999
88029
  if (!existingToolCall) {
@@ -88020,13 +88050,14 @@ var ACPLanguageModel = class {
88020
88050
  });
88021
88051
  } else if (!existingToolCall.inputAvailable && hasInput) {
88022
88052
  existingToolCall.inputAvailable = true;
88053
+ if (update$1.title && existingToolCall.name !== update$1.title && update$1.title !== toolCallId) existingToolCall.name = update$1.title;
88023
88054
  controller.enqueue({
88024
88055
  type: "tool-call",
88025
88056
  toolCallId,
88026
88057
  toolName: ACP_PROVIDER_AGENT_DYNAMIC_TOOL_NAME2,
88027
88058
  input: JSON.stringify({
88028
88059
  toolCallId,
88029
- toolName,
88060
+ toolName: existingToolCall.name,
88030
88061
  args: toolInput
88031
88062
  })
88032
88063
  });
@@ -88053,13 +88084,14 @@ var ACPLanguageModel = class {
88053
88084
  }
88054
88085
  if (!toolInfo.inputAvailable) {
88055
88086
  toolInfo.inputAvailable = true;
88087
+ if (update$1.title && toolInfo.name !== update$1.title && update$1.title !== toolCallId) toolInfo.name = update$1.title;
88056
88088
  controller.enqueue({
88057
88089
  type: "tool-call",
88058
88090
  toolCallId,
88059
88091
  toolName: ACP_PROVIDER_AGENT_DYNAMIC_TOOL_NAME2,
88060
88092
  input: JSON.stringify({
88061
88093
  toolCallId,
88062
- toolName,
88094
+ toolName: toolInfo.name,
88063
88095
  args: {}
88064
88096
  })
88065
88097
  });
@@ -88085,13 +88117,14 @@ var ACPLanguageModel = class {
88085
88117
  });
88086
88118
  } else if (!toolInfo.inputAvailable) {
88087
88119
  toolInfo.inputAvailable = true;
88120
+ if (update$1.title && toolInfo.name !== update$1.title && update$1.title !== toolCallId) toolInfo.name = update$1.title;
88088
88121
  controller.enqueue({
88089
88122
  type: "tool-call",
88090
88123
  toolCallId,
88091
88124
  toolName: ACP_PROVIDER_AGENT_DYNAMIC_TOOL_NAME2,
88092
88125
  input: JSON.stringify({
88093
88126
  toolCallId,
88094
- toolName,
88127
+ toolName: toolInfo.name,
88095
88128
  args: {}
88096
88129
  })
88097
88130
  });
@@ -88118,7 +88151,6 @@ var ACPLanguageModel = class {
88118
88151
  try {
88119
88152
  await this.ensureConnected();
88120
88153
  const promptContent = convertAiSdkMessagesToAcp(options, this.isFreshSession);
88121
- console.log(`###########`, promptContent);
88122
88154
  this.isFreshSession = false;
88123
88155
  let accumulatedText = "";
88124
88156
  const toolCalls = [];
@@ -88325,6 +88357,36 @@ function createACPProvider(config) {
88325
88357
  return new ACPProvider(config);
88326
88358
  }
88327
88359
 
88360
+ //#endregion
88361
+ //#region src/utils/npm-package.ts
88362
+ /**
88363
+ * Resolve npm package bin entry point
88364
+ * Returns the absolute path to the bin file, or null if resolution fails
88365
+ */
88366
+ function resolveNpmPackageBin(packageName) {
88367
+ try {
88368
+ const packageJsonPath = createRequire$1(import.meta.url).resolve(`${packageName}/package.json`);
88369
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
88370
+ let binPath;
88371
+ if (typeof packageJson.bin === "string") binPath = packageJson.bin;
88372
+ else if (typeof packageJson.bin === "object") {
88373
+ const binEntries = Object.entries(packageJson.bin);
88374
+ const matchingEntry = binEntries.find(([name]) => name === packageJson.name.split("/").pop());
88375
+ binPath = matchingEntry ? matchingEntry[1] : binEntries[0]?.[1];
88376
+ }
88377
+ if (!binPath) {
88378
+ console.warn(`[dev-inspector] [acp] No bin entry found in ${packageName}/package.json`);
88379
+ return null;
88380
+ }
88381
+ const binFullPath = join(dirname(packageJsonPath), binPath);
88382
+ console.log(`[dev-inspector] [acp] Resolved ${packageName} bin to: ${binFullPath}`);
88383
+ return binFullPath;
88384
+ } catch (error) {
88385
+ console.warn(`[dev-inspector] [acp] Failed to resolve npm package ${packageName}:`, error);
88386
+ return null;
88387
+ }
88388
+ }
88389
+
88328
88390
  //#endregion
88329
88391
  //#region src/middleware/acp-middleware.ts
88330
88392
  /**
@@ -88393,10 +88455,13 @@ async function loadMcpToolsV5(transport) {
88393
88455
  inputSchema: jsonSchema(toolInfo.inputSchema),
88394
88456
  execute: async (args) => {
88395
88457
  console.log(`[dev-inspector] [acp] Executing MCP tool: ${toolName}`);
88396
- return await callMcpMethodViaTransport(transport, "tools/call", {
88458
+ const result = await callMcpMethodViaTransport(transport, "tools/call", {
88397
88459
  name: toolName,
88398
88460
  arguments: args
88399
88461
  });
88462
+ const parsedResult = CallToolResultSchema.safeParse(result);
88463
+ if (!parsedResult.success) return result;
88464
+ return parsedResult.data?.content?.map((item) => item?.text).join("\n");
88400
88465
  }
88401
88466
  });
88402
88467
  }
@@ -88440,7 +88505,7 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
88440
88505
  * Returns: { sessionId }
88441
88506
  */
88442
88507
  middlewares.use("/api/acp/init-session", async (req, res) => {
88443
- if (handleCors(res, req.method)) return;
88508
+ if (handleCors(req, res)) return;
88444
88509
  if (req.method !== "POST") {
88445
88510
  res.statusCode = 405;
88446
88511
  res.end("Method Not Allowed");
@@ -88486,9 +88551,19 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
88486
88551
  return;
88487
88552
  }
88488
88553
  console.log(`[dev-inspector] [acp] Creating new global provider for ${agent.name}`);
88554
+ let command = agent.command;
88555
+ let args = agent.args;
88556
+ if (agent.npmPackage) {
88557
+ const binPath = resolveNpmPackageBin(agent.npmPackage);
88558
+ if (binPath) {
88559
+ command = binPath;
88560
+ args = agent.npmArgs || [];
88561
+ console.log(`[dev-inspector] [acp] Using resolved npm package: ${agent.npmPackage}`);
88562
+ } else console.log(`[dev-inspector] [acp] Failed to resolve npm package, falling back to: ${agent.command}`);
88563
+ }
88489
88564
  provider = createACPProvider({
88490
- command: agent.command,
88491
- args: agent.args,
88565
+ command,
88566
+ args,
88492
88567
  env: {
88493
88568
  ...process.env,
88494
88569
  ...envVars
@@ -88557,7 +88632,7 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
88557
88632
  * Body: { sessionId }
88558
88633
  */
88559
88634
  middlewares.use("/api/acp/cleanup-session", async (req, res) => {
88560
- if (handleCors(res, req.method)) return;
88635
+ if (handleCors(req, res)) return;
88561
88636
  if (req.method !== "POST") {
88562
88637
  res.statusCode = 405;
88563
88638
  res.end("Method Not Allowed");
@@ -88600,7 +88675,7 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
88600
88675
  * Body: { messages, agent, envVars, sessionId? }
88601
88676
  */
88602
88677
  middlewares.use("/api/acp/chat", async (req, res) => {
88603
- if (handleCors(res, req.method)) return;
88678
+ if (handleCors(req, res)) return;
88604
88679
  if (req.method !== "POST") {
88605
88680
  res.statusCode = 405;
88606
88681
  res.end("Method Not Allowed");
@@ -88623,9 +88698,19 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
88623
88698
  shouldCleanupProvider = false;
88624
88699
  } else {
88625
88700
  console.log(`[dev-inspector] [acp] Creating new provider (no session found or provided)`);
88701
+ let command = agent.command;
88702
+ let args = agent.args;
88703
+ if (agent.npmPackage) {
88704
+ const binPath = resolveNpmPackageBin(agent.npmPackage);
88705
+ if (binPath) {
88706
+ command = binPath;
88707
+ args = agent.npmArgs || [];
88708
+ console.log(`[dev-inspector] [acp] Using resolved npm package: ${agent.npmPackage}`);
88709
+ }
88710
+ }
88626
88711
  provider = createACPProvider({
88627
- command: agent.command,
88628
- args: agent.args,
88712
+ command,
88713
+ args,
88629
88714
  env: {
88630
88715
  ...process.env,
88631
88716
  ...envVars