@path58/p58-n8n 0.2.4 → 0.2.6

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/AGENT_INSTALL.md CHANGED
@@ -232,4 +232,4 @@ Once installed, the user can ask their AI assistant to:
232
232
 
233
233
  ---
234
234
 
235
- **Package:** `@path58/p58-n8n` | **npm:** https://www.npmjs.com/package/@path58/p58-n8n | **Version:** 0.2.4+
235
+ **Package:** `@path58/p58-n8n` | **npm:** https://www.npmjs.com/package/@path58/p58-n8n | **Version:** 0.2.6+
package/CHANGELOG.md CHANGED
@@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.2.6] - 2026-03-11
9
+
10
+ ### Added
11
+
12
+ - **LangChain AI connection type support** — `build_workflow` now automatically detects and wires all 10 LangChain connection types (`ai_languageModel`, `ai_tool`, `ai_memory`, `ai_embedding`, `ai_outputParser`, `ai_document`, `ai_vectorStore`, `ai_textSplitter`, `ai_retriever`, `ai_reranker`) instead of hardcoding all connections as `main`
13
+ - **Sub-node positioning** — LLM models, memory modules, and tools now position below their parent chain/agent node in the n8n UI (same X, Y+200), matching native n8n layout conventions
14
+ - **3-tier connection type resolver** — explicit user override → `connection_rules` catalog lookup (496 AI rules) → `ai_nodes.ai_type` fallback → `main` default
15
+ - **`is_sub_node` metadata coverage** — backfilled from ~45% to 98.4% across all AI nodes in catalog
16
+
17
+ ### Fixed
18
+
19
+ - LangChain workflows now deploy with correct connection wiring — models appear on diamond ports, not circle ports
20
+ - v0.2.5 was published with stale bundle (did not include LangChain fix); this release rebuilds from fixed source with correct `SERVER_VERSION`
21
+
22
+ ## [0.2.5] - 2026-03-11
23
+
24
+ ### Fixed
25
+
26
+ - Internal release — npm publish from stale source (superseded by v0.2.6)
27
+
8
28
  ## [0.2.4] - 2026-03-10
9
29
 
10
30
  ### Added
@@ -130,6 +150,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
130
150
  - npm package published as `@path58/p58-n8n`
131
151
  - ESM module support with shebang for direct `npx` execution
132
152
 
153
+ [0.2.6]: https://github.com/tsvika58/p58-n8n/releases/tag/v0.2.6
154
+ [0.2.5]: https://github.com/tsvika58/p58-n8n/releases/tag/v0.2.5
133
155
  [0.2.4]: https://github.com/tsvika58/p58-n8n/releases/tag/v0.2.4
134
156
  [0.2.3]: https://github.com/tsvika58/p58-n8n/releases/tag/v0.2.3
135
157
  [0.2.2]: https://github.com/tsvika58/p58-n8n/releases/tag/v0.2.2
@@ -3111,7 +3111,7 @@ var require_retryUtils = __commonJS({
3111
3111
  "use strict";
3112
3112
  Object.defineProperty(exports2, "__esModule", { value: true });
3113
3113
  exports2.retry = retry;
3114
- exports2.retryDbQuery = retryDbQuery9;
3114
+ exports2.retryDbQuery = retryDbQuery10;
3115
3115
  var logger_1 = require_logger();
3116
3116
  var DEFAULT_OPTIONS = {
3117
3117
  maxRetries: 3,
@@ -3170,7 +3170,7 @@ var require_retryUtils = __commonJS({
3170
3170
  }
3171
3171
  throw lastError || new Error(`${operationName} failed after ${config3.maxRetries} retries`);
3172
3172
  }
3173
- async function retryDbQuery9(queryFn, maxRetries = DEFAULT_OPTIONS.maxRetries, operationName = "Database query") {
3173
+ async function retryDbQuery10(queryFn, maxRetries = DEFAULT_OPTIONS.maxRetries, operationName = "Database query") {
3174
3174
  return retry(queryFn, { maxRetries }, operationName);
3175
3175
  }
3176
3176
  }
@@ -18473,7 +18473,7 @@ var import_types22 = require("@modelcontextprotocol/sdk/types.js");
18473
18473
  var config = {
18474
18474
  // Server identity
18475
18475
  SERVER_NAME: "p58-n8n",
18476
- SERVER_VERSION: "0.2.4",
18476
+ SERVER_VERSION: "0.2.6",
18477
18477
  // Database configuration (from environment)
18478
18478
  SUPABASE_URL: process.env.SUPABASE_URL,
18479
18479
  SUPABASE_KEY: process.env.SUPABASE_KEY,
@@ -41483,14 +41483,15 @@ Examples:
41483
41483
  // dist/generation/build/WorkflowBuilder.js
41484
41484
  var import_crypto4 = require("crypto");
41485
41485
  init_validatorPostgresClient();
41486
- var import_retry7 = __toESM(require_retryUtils(), 1);
41487
- var import_logging53 = __toESM(require_logging(), 1);
41486
+ var import_retry8 = __toESM(require_retryUtils(), 1);
41487
+ var import_logging54 = __toESM(require_logging(), 1);
41488
41488
 
41489
41489
  // dist/generation/build/PositionCalculator.js
41490
41490
  var HORIZONTAL_SPACING = 250;
41491
41491
  var VERTICAL_SPACING = 150;
41492
41492
  var START_X = 250;
41493
41493
  var START_Y = 300;
41494
+ var SUB_NODE_Y_OFFSET = 200;
41494
41495
  function findRootNodes(nodeNames, connections) {
41495
41496
  const hasIncoming = new Set(connections.map((c) => c.to));
41496
41497
  const roots = nodeNames.filter((name) => !hasIncoming.has(name));
@@ -41542,14 +41543,45 @@ function assignFallbacks(nodeNames, positions) {
41542
41543
  }
41543
41544
  }
41544
41545
  }
41545
- function calculatePositions(nodeNames, connections) {
41546
+ function detectSubNodes(connections, resolvedTypes) {
41547
+ const subNodes = /* @__PURE__ */ new Set();
41548
+ const parentOf = /* @__PURE__ */ new Map();
41549
+ for (const conn of connections) {
41550
+ const connType = resolvedTypes.get(`${conn.from}\u2192${conn.to}`);
41551
+ if (connType && connType !== "main") {
41552
+ subNodes.add(conn.from);
41553
+ parentOf.set(conn.from, conn.to);
41554
+ }
41555
+ }
41556
+ return { subNodes, parentOf };
41557
+ }
41558
+ function assignSubNodePositions(subNodes, parentOf, positions) {
41559
+ const countPerParent = /* @__PURE__ */ new Map();
41560
+ for (const subNode of subNodes) {
41561
+ const parent = parentOf.get(subNode);
41562
+ if (!parent)
41563
+ continue;
41564
+ const parentPos = positions.get(parent);
41565
+ if (!parentPos)
41566
+ continue;
41567
+ const count = countPerParent.get(parent) ?? 0;
41568
+ positions.set(subNode, [parentPos[0], parentPos[1] + SUB_NODE_Y_OFFSET * (count + 1)]);
41569
+ countPerParent.set(parent, count + 1);
41570
+ }
41571
+ }
41572
+ function calculatePositions(nodeNames, connections, resolvedTypes) {
41546
41573
  const positions = /* @__PURE__ */ new Map();
41547
41574
  if (nodeNames.length === 0)
41548
41575
  return positions;
41549
- const roots = findRootNodes(nodeNames, connections);
41550
- const adjacency = buildAdjacency(connections);
41576
+ const { subNodes, parentOf } = resolvedTypes ? detectSubNodes(connections, resolvedTypes) : { subNodes: /* @__PURE__ */ new Set(), parentOf: /* @__PURE__ */ new Map() };
41577
+ const mainNames = nodeNames.filter((n) => !subNodes.has(n));
41578
+ const mainConns = connections.filter((c) => !subNodes.has(c.from));
41579
+ const roots = findRootNodes(mainNames, mainConns);
41580
+ const adjacency = buildAdjacency(mainConns);
41551
41581
  assignRootPositions(roots, positions);
41552
41582
  bfsAssign(roots, adjacency, positions);
41583
+ assignFallbacks(mainNames, positions);
41584
+ assignSubNodePositions(subNodes, parentOf, positions);
41553
41585
  assignFallbacks(nodeNames, positions);
41554
41586
  return positions;
41555
41587
  }
@@ -41662,6 +41694,117 @@ function getResourceLocatorParams(nodeType) {
41662
41694
  return RESOURCE_LOCATOR_PARAMS[nodeType.toLowerCase()];
41663
41695
  }
41664
41696
 
41697
+ // dist/generation/build/connectionTypeResolver.js
41698
+ init_validatorPostgresClient();
41699
+ var import_retry7 = __toESM(require_retryUtils(), 1);
41700
+ var import_logging53 = __toESM(require_logging(), 1);
41701
+ var AI_TYPE_TO_CONNECTION_TYPE = {
41702
+ llm: "ai_languageModel",
41703
+ memory: "ai_memory",
41704
+ tool: "ai_tool",
41705
+ embedding: "ai_embedding",
41706
+ output_parser: "ai_outputParser",
41707
+ retriever: "ai_retriever",
41708
+ document_loader: "ai_document",
41709
+ text_splitter: "ai_textSplitter",
41710
+ vector_store: "ai_vectorStore",
41711
+ reranker: "ai_reranker"
41712
+ };
41713
+ var DEFAULT_CONNECTION_TYPE = "main";
41714
+ async function loadConnectionRules2() {
41715
+ const { rows } = await (0, import_retry7.retryDbQuery)(() => validatorQuery(`SELECT LOWER(source_node_type) AS source_node_type,
41716
+ LOWER(target_node_type) AS target_node_type,
41717
+ source_output
41718
+ FROM bluelime.connection_rules
41719
+ WHERE source_output != 'main'
41720
+ AND is_valid = true
41721
+ ORDER BY occurrence_count DESC`), 2, "connectionTypeResolver:loadConnectionRules");
41722
+ return rows;
41723
+ }
41724
+ async function loadAINodeTypes() {
41725
+ const { rows } = await (0, import_retry7.retryDbQuery)(() => validatorQuery(`SELECT LOWER(n.node_type) AS node_type, ai.ai_type
41726
+ FROM bluelime.ai_nodes ai
41727
+ JOIN bluelime.nodes n ON ai.node_id = n.id
41728
+ WHERE ai.is_sub_node = true
41729
+ AND ai.ai_type IS NOT NULL`), 2, "connectionTypeResolver:loadAINodeTypes");
41730
+ return rows;
41731
+ }
41732
+ function buildRuleMap(rows) {
41733
+ const map = /* @__PURE__ */ new Map();
41734
+ for (const row of rows) {
41735
+ const key = `${row.source_node_type}|${row.target_node_type}`;
41736
+ if (!map.has(key))
41737
+ map.set(key, row.source_output);
41738
+ }
41739
+ return map;
41740
+ }
41741
+ function buildAITypeMap(rows) {
41742
+ const map = /* @__PURE__ */ new Map();
41743
+ for (const row of rows) {
41744
+ const connType = AI_TYPE_TO_CONNECTION_TYPE[row.ai_type];
41745
+ if (connType && !map.has(row.node_type))
41746
+ map.set(row.node_type, connType);
41747
+ }
41748
+ return map;
41749
+ }
41750
+ var ConnectionTypeResolver = class _ConnectionTypeResolver {
41751
+ ruleMap;
41752
+ aiTypeMap;
41753
+ constructor(ruleMap, aiTypeMap) {
41754
+ this.ruleMap = ruleMap;
41755
+ this.aiTypeMap = aiTypeMap;
41756
+ }
41757
+ /**
41758
+ * Factory: load catalog data and return a ready resolver.
41759
+ * Falls back to empty maps (all "main") if DB query fails.
41760
+ */
41761
+ static async create() {
41762
+ try {
41763
+ const [ruleRows, aiNodeRows] = await Promise.all([
41764
+ loadConnectionRules2(),
41765
+ loadAINodeTypes()
41766
+ ]);
41767
+ import_logging53.logger.debug("connectionTypeResolver: loaded catalog", {
41768
+ ruleCount: ruleRows.length,
41769
+ aiNodeCount: aiNodeRows.length
41770
+ });
41771
+ return new _ConnectionTypeResolver(buildRuleMap(ruleRows), buildAITypeMap(aiNodeRows));
41772
+ } catch (err) {
41773
+ import_logging53.logger.warn('connectionTypeResolver: DB load failed, defaulting all connections to "main"', { error: err });
41774
+ return new _ConnectionTypeResolver(/* @__PURE__ */ new Map(), /* @__PURE__ */ new Map());
41775
+ }
41776
+ }
41777
+ /**
41778
+ * Resolve the n8n connection type for a single connection.
41779
+ *
41780
+ * @param explicit - Caller-provided override (e.g., from BuildConnectionSpec.type)
41781
+ * @param sourceNodeType - Lowercased full n8n type of the source node
41782
+ * @param targetNodeType - Lowercased full n8n type of the target node
41783
+ * @returns Resolved connection type string
41784
+ */
41785
+ resolve(explicit, sourceNodeType, targetNodeType) {
41786
+ if (explicit)
41787
+ return explicit;
41788
+ if (sourceNodeType && targetNodeType) {
41789
+ const catalogType = this.ruleMap.get(`${sourceNodeType}|${targetNodeType}`);
41790
+ if (catalogType)
41791
+ return catalogType;
41792
+ }
41793
+ if (sourceNodeType) {
41794
+ const aiType = this.aiTypeMap.get(sourceNodeType);
41795
+ if (aiType)
41796
+ return aiType;
41797
+ }
41798
+ return DEFAULT_CONNECTION_TYPE;
41799
+ }
41800
+ };
41801
+ function buildNodeTypeMap4(nodes) {
41802
+ const map = /* @__PURE__ */ new Map();
41803
+ for (const node of nodes)
41804
+ map.set(node.name, node.type.toLowerCase());
41805
+ return map;
41806
+ }
41807
+
41665
41808
  // dist/generation/build/version-credential-resolver.js
41666
41809
  var FALLBACK_VERSION = 1;
41667
41810
  var UNKNOWN_AUTH_MODE = "unknown";
@@ -42242,7 +42385,7 @@ function buildPlaceholders(count) {
42242
42385
  async function queryTypeVersions(nodeTypes) {
42243
42386
  const normalized = nodeTypes.map((t) => t.toLowerCase());
42244
42387
  const placeholders = buildPlaceholders(normalized.length);
42245
- const { rows } = await (0, import_retry7.retryDbQuery)(() => validatorQuery(`SELECT node_type, default_version, supported_versions FROM bluelime.nodes WHERE LOWER(node_type) IN (${placeholders})`, normalized), 3, "build_workflow_typeversion_batch");
42388
+ const { rows } = await (0, import_retry8.retryDbQuery)(() => validatorQuery(`SELECT node_type, default_version, supported_versions FROM bluelime.nodes WHERE LOWER(node_type) IN (${placeholders})`, normalized), 3, "build_workflow_typeversion_batch");
42246
42389
  const groups = /* @__PURE__ */ new Map();
42247
42390
  for (const row of rows) {
42248
42391
  const key = row.node_type.toLowerCase();
@@ -42433,7 +42576,7 @@ function findTerminalNodes(nodes, connections) {
42433
42576
  function buildNodeBase(spec, position, typeVersion, casingMap) {
42434
42577
  const correctedType = resolveNodeTypeCasing(spec.type, casingMap);
42435
42578
  if (correctedType !== spec.type) {
42436
- import_logging53.logger.debug("build_workflow: corrected node type casing", { original: spec.type, corrected: correctedType, nodeName: spec.name });
42579
+ import_logging54.logger.debug("build_workflow: corrected node type casing", { original: spec.type, corrected: correctedType, nodeName: spec.name });
42437
42580
  }
42438
42581
  return {
42439
42582
  id: (0, import_crypto4.randomUUID)(),
@@ -42455,20 +42598,20 @@ function assembleNode(spec, position, typeVersion, credential, isTerminal, casin
42455
42598
  node.continueOnFail = true;
42456
42599
  return node;
42457
42600
  }
42458
- function assembleConnections(connections) {
42601
+ function assembleConnections(connections, nodeTypeMap, resolver) {
42459
42602
  const result = {};
42460
42603
  for (const conn of connections) {
42604
+ const sourceType = nodeTypeMap.get(conn.from);
42605
+ const targetType = nodeTypeMap.get(conn.to);
42606
+ const connType = resolver.resolve(conn.type, sourceType, targetType);
42461
42607
  if (!result[conn.from])
42462
- result[conn.from] = { main: [] };
42608
+ result[conn.from] = {};
42609
+ if (!result[conn.from][connType])
42610
+ result[conn.from][connType] = [];
42463
42611
  const outputIdx = conn.from_output ?? 0;
42464
- while (result[conn.from].main.length <= outputIdx) {
42465
- result[conn.from].main.push([]);
42466
- }
42467
- result[conn.from].main[outputIdx].push({
42468
- node: conn.to,
42469
- type: "main",
42470
- index: conn.to_input ?? 0
42471
- });
42612
+ while (result[conn.from][connType].length <= outputIdx)
42613
+ result[conn.from][connType].push([]);
42614
+ result[conn.from][connType][outputIdx].push({ node: conn.to, type: connType, index: conn.to_input ?? 0 });
42472
42615
  }
42473
42616
  return result;
42474
42617
  }
@@ -42479,36 +42622,49 @@ async function resolveCatalogData(input) {
42479
42622
  const uniqueTypes = [...new Set(input.nodes.map((n) => n.type))];
42480
42623
  const [typeResult, credentialMap] = await Promise.all([
42481
42624
  queryTypeVersions(uniqueTypes).catch((err) => {
42482
- import_logging53.logger.warn("WorkflowBuilder: typeVersion lookup failed, using defaults", { error: err });
42625
+ import_logging54.logger.warn("WorkflowBuilder: typeVersion lookup failed, using defaults", { error: err });
42483
42626
  return { versions: /* @__PURE__ */ new Map(), casingMap: /* @__PURE__ */ new Map() };
42484
42627
  }),
42485
42628
  resolveAllCredentials(input.nodes)
42486
42629
  ]);
42487
42630
  return { versionMap: typeResult.versions, casingMap: typeResult.casingMap, credentialMap };
42488
42631
  }
42489
- function buildNodeList(nodes, connections, versionMap, casingMap, credentialMap) {
42490
- const autoPositions = calculatePositions(nodes.map((n) => n.name), connections);
42632
+ function computeResolvedTypes(connections, nodeTypeMap, resolver) {
42633
+ const map = /* @__PURE__ */ new Map();
42634
+ for (const conn of connections) {
42635
+ const connType = resolver.resolve(conn.type, nodeTypeMap.get(conn.from), nodeTypeMap.get(conn.to));
42636
+ map.set(`${conn.from}\u2192${conn.to}`, connType);
42637
+ }
42638
+ return map;
42639
+ }
42640
+ function buildNodeList(nodes, connections, versionMap, casingMap, credentialMap, nodeTypeMap, resolver) {
42641
+ const resolvedTypes = computeResolvedTypes(connections, nodeTypeMap, resolver);
42642
+ const autoPositions = calculatePositions(nodes.map((n) => n.name), connections, resolvedTypes);
42491
42643
  const terminalNodes = findTerminalNodes(nodes, connections);
42492
42644
  return nodes.map((spec) => {
42493
42645
  const resolved = resolveNodeVersion(spec, versionMap, credentialMap);
42494
- import_logging53.logger.debug("build_workflow: typeVersion resolved", { nodeType: spec.type, nodeName: spec.name, ...resolved });
42646
+ import_logging54.logger.debug("build_workflow: typeVersion resolved", { nodeType: spec.type, nodeName: spec.name, ...resolved });
42495
42647
  return assembleNode(spec, getNodePosition(spec, autoPositions), resolved.typeVersion, credentialMap.get(spec.name), terminalNodes.has(spec.name), casingMap);
42496
42648
  });
42497
42649
  }
42498
42650
  async function assembleWorkflow(input) {
42499
- const { versionMap, casingMap, credentialMap } = await resolveCatalogData(input);
42500
- const nodes = buildNodeList(input.nodes, input.connections, versionMap, casingMap, credentialMap);
42651
+ const [{ versionMap, casingMap, credentialMap }, resolver] = await Promise.all([
42652
+ resolveCatalogData(input),
42653
+ ConnectionTypeResolver.create()
42654
+ ]);
42655
+ const nodeTypeMap = buildNodeTypeMap4(input.nodes);
42656
+ const nodes = buildNodeList(input.nodes, input.connections, versionMap, casingMap, credentialMap, nodeTypeMap, resolver);
42501
42657
  return {
42502
42658
  name: input.name,
42503
42659
  nodes,
42504
- connections: assembleConnections(input.connections),
42660
+ connections: assembleConnections(input.connections, nodeTypeMap, resolver),
42505
42661
  settings: {},
42506
42662
  staticData: null
42507
42663
  };
42508
42664
  }
42509
42665
 
42510
42666
  // dist/generation/build/SubWorkflowBuilder.js
42511
- var import_logging54 = __toESM(require_logging(), 1);
42667
+ var import_logging55 = __toESM(require_logging(), 1);
42512
42668
  var EXECUTE_WORKFLOW_TYPE = "n8n-nodes-base.executeWorkflow";
42513
42669
  var PLACEHOLDER = "{{SUB_WORKFLOW_ID}}";
42514
42670
  function findExecuteWorkflowNodes(nodes) {
@@ -42541,17 +42697,17 @@ async function buildSubWorkflows(parentSpec, buildSingle) {
42541
42697
  }
42542
42698
  const builtSubWorkflows = [];
42543
42699
  for (const subSpec of parentSpec.sub_workflows) {
42544
- import_logging54.logger.info("SubWorkflowBuilder: building sub-workflow", { name: subSpec.name });
42700
+ import_logging55.logger.info("SubWorkflowBuilder: building sub-workflow", { name: subSpec.name });
42545
42701
  const { workflow_id, workflow_url } = await buildSingle(subSpec);
42546
42702
  builtSubWorkflows.push({ name: subSpec.name, workflow_id, workflow_url });
42547
- import_logging54.logger.info("SubWorkflowBuilder: sub-workflow built", { name: subSpec.name, workflow_id });
42703
+ import_logging55.logger.info("SubWorkflowBuilder: sub-workflow built", { name: subSpec.name, workflow_id });
42548
42704
  }
42549
42705
  const wiredSpec = wireSubWorkflowIds(parentSpec, builtSubWorkflows);
42550
42706
  return { wiredSpec, builtSubWorkflows };
42551
42707
  }
42552
42708
 
42553
42709
  // dist/mcp/tools/handlers/build-workflow.js
42554
- var import_logging55 = __toESM(require_logging(), 1);
42710
+ var import_logging56 = __toESM(require_logging(), 1);
42555
42711
  function buildWorkflowUrl(workflowId) {
42556
42712
  const apiBase = process.env.N8N_API_BASE_URL ?? "http://localhost:5678/api/v1";
42557
42713
  return `${apiBase.replace("/api/v1", "")}/workflow/${workflowId}`;
@@ -42644,7 +42800,7 @@ function buildSuccessPayload(args, result, builtSubWorkflows, workflowId, testRe
42644
42800
  async function buildSuccessResponse2(args, result, builtSubWorkflows, timeoutMs, startTime) {
42645
42801
  const workflowId = result.serverResponse.id;
42646
42802
  const testResult = args.test !== false ? await runTestStep(result.finalWorkflow, workflowId, args.test_payload, timeoutMs) : void 0;
42647
- import_logging55.logger.info("build_workflow: complete", { workflowId, fixes: result.fixesApplied.length });
42803
+ import_logging56.logger.info("build_workflow: complete", { workflowId, fixes: result.fixesApplied.length });
42648
42804
  return buildSuccessPayload(args, result, builtSubWorkflows, workflowId, testResult, startTime);
42649
42805
  }
42650
42806
  async function executeBuildPipeline(args, timeoutMs, correlationId, startTime) {
@@ -42778,7 +42934,7 @@ function stripExtraWebhookTriggers(args) {
42778
42934
  const webhookNames = new Set(webhookNodes.map((n) => n.name));
42779
42935
  const cleanedNodes = args.nodes.filter((n) => !webhookNames.has(n.name));
42780
42936
  const cleanedConnections = args.connections?.filter((c) => !webhookNames.has(c.from) && !webhookNames.has(c.to));
42781
- import_logging55.logger.info("build_workflow: stripped webhook triggers from schedule workflow", {
42937
+ import_logging56.logger.info("build_workflow: stripped webhook triggers from schedule workflow", {
42782
42938
  removed: [...webhookNames]
42783
42939
  });
42784
42940
  return {
@@ -42793,7 +42949,7 @@ async function handleBuildWorkflow(args) {
42793
42949
  const correlationId = generateCorrelationId();
42794
42950
  const startTime = performance.now();
42795
42951
  const timeoutMs = normalizeTimeout();
42796
- import_logging55.logger.debug("build_workflow: starting", { correlationId, workflowName: args.name });
42952
+ import_logging56.logger.debug("build_workflow: starting", { correlationId, workflowName: args.name });
42797
42953
  try {
42798
42954
  const { cleaned: triggerCleaned, warnings: triggerWarnings } = await substituteUnavailableTriggers(args);
42799
42955
  const { cleaned, warning: webhookWarning } = stripExtraWebhookTriggers(triggerCleaned);
@@ -42822,7 +42978,7 @@ async function handleBuildWorkflow(args) {
42822
42978
  } catch (error) {
42823
42979
  if (isTimeoutError(error))
42824
42980
  return toMCPResponse(createTimeoutError(correlationId, "build_workflow"));
42825
- import_logging55.logger.error("build_workflow: unexpected error", { correlationId, error });
42981
+ import_logging56.logger.error("build_workflow: unexpected error", { correlationId, error });
42826
42982
  const e = error instanceof Error ? error : new Error(String(error));
42827
42983
  return toMCPResponse(createInternalError(correlationId, e));
42828
42984
  }
@@ -42876,14 +43032,15 @@ Examples:
42876
43032
  },
42877
43033
  connections: {
42878
43034
  type: "array",
42879
- description: "Node connections",
43035
+ description: "Node connections. For LangChain/AI nodes the connection type is auto-detected from the catalog \u2014 no need to set `type` manually. Use `type` only to override auto-detection.",
42880
43036
  items: {
42881
43037
  type: "object",
42882
43038
  properties: {
42883
43039
  from: { type: "string", description: "Source node name" },
42884
43040
  to: { type: "string", description: "Target node name" },
42885
43041
  from_output: { type: "number", description: "Output port index (default 0)" },
42886
- to_input: { type: "number", description: "Input port index (default 0)" }
43042
+ to_input: { type: "number", description: "Input port index (default 0)" },
43043
+ type: { type: "string", description: 'Connection type override (e.g., "ai_languageModel", "ai_tool", "ai_memory"). Auto-resolved from catalog if omitted.' }
42887
43044
  },
42888
43045
  required: ["from", "to"]
42889
43046
  }
@@ -42902,7 +43059,7 @@ Examples:
42902
43059
  };
42903
43060
 
42904
43061
  // dist/mcp/tools/handlers/list-credentials.js
42905
- var import_logging56 = __toESM(require_logging(), 1);
43062
+ var import_logging57 = __toESM(require_logging(), 1);
42906
43063
  init_validatorPostgresClient();
42907
43064
  function buildApiConfig14(timeoutMs) {
42908
43065
  return {
@@ -43008,10 +43165,10 @@ function handleListError2(error, correlationId) {
43008
43165
  }
43009
43166
  const statusCode = error?.statusCode;
43010
43167
  if (statusCode === 401 || statusCode === 403) {
43011
- import_logging56.logger.warn("list_credentials: auth error", { correlationId, statusCode });
43168
+ import_logging57.logger.warn("list_credentials: auth error", { correlationId, statusCode });
43012
43169
  return toMCPResponse(createSuccessResponse({ success: false, error: "Authentication failed" }, correlationId, { duration_ms: 0 }));
43013
43170
  }
43014
- import_logging56.logger.error("list_credentials: unexpected error", { correlationId, error });
43171
+ import_logging57.logger.error("list_credentials: unexpected error", { correlationId, error });
43015
43172
  const originalError = error instanceof Error ? error : new Error(String(error));
43016
43173
  return toMCPResponse(createInternalError(correlationId, originalError));
43017
43174
  }
@@ -43022,13 +43179,13 @@ async function handleListCredentials(args) {
43022
43179
  const correlationId = generateCorrelationId();
43023
43180
  const startTime = performance.now();
43024
43181
  const timeoutMs = normalizeTimeout();
43025
- import_logging56.logger.debug("list_credentials: starting", { correlationId, options: args });
43182
+ import_logging57.logger.debug("list_credentials: starting", { correlationId, options: args });
43026
43183
  try {
43027
43184
  const result = await fetchRawCredentials(args, timeoutMs);
43028
43185
  const { credentials: filtered, neededCredentialTypes } = await applyForNodesFilter(result.credentials, args.forNodes);
43029
43186
  const enriched = await enrichWithNodeTypes(filtered);
43030
43187
  const final = args.includeSchema ? await enrichWithSchema(enriched) : enriched;
43031
- import_logging56.logger.info("list_credentials: retrieved", { correlationId, count: final.length });
43188
+ import_logging57.logger.info("list_credentials: retrieved", { correlationId, count: final.length });
43032
43189
  const data = buildResponseData(final, neededCredentialTypes);
43033
43190
  return toMCPResponse(createSuccessResponse(data, correlationId, { duration_ms: Math.round(performance.now() - startTime) }));
43034
43191
  } catch (error) {
@@ -43084,7 +43241,7 @@ listing which credential types need to be created.`,
43084
43241
  };
43085
43242
 
43086
43243
  // dist/mcp/tools/handlers/get-credential-schema.js
43087
- var import_logging57 = __toESM(require_logging(), 1);
43244
+ var import_logging58 = __toESM(require_logging(), 1);
43088
43245
  init_validatorPostgresClient();
43089
43246
  var SENSITIVE_PATTERNS = /* @__PURE__ */ new Set([
43090
43247
  "apikey",
@@ -43223,21 +43380,21 @@ function buildResult(credentialType, rows, compatibleNodes) {
43223
43380
  function buildSchemaResponse(credentialType, rows, nodes, correlationId, startTime) {
43224
43381
  const data = buildResult(credentialType, rows, nodes);
43225
43382
  const duration_ms = Math.round(performance.now() - startTime);
43226
- import_logging57.logger.info("get_credential_schema: found", { correlationId, credential_type: credentialType, fieldCount: rows.length });
43383
+ import_logging58.logger.info("get_credential_schema: found", { correlationId, credential_type: credentialType, fieldCount: rows.length });
43227
43384
  return toMCPResponse(createSuccessResponse(data, correlationId, { duration_ms }));
43228
43385
  }
43229
43386
  async function handleGetCredentialSchema(args) {
43230
43387
  const correlationId = generateCorrelationId();
43231
43388
  const startTime = performance.now();
43232
43389
  const { credential_type } = args;
43233
- import_logging57.logger.debug("get_credential_schema: starting", { correlationId, credential_type });
43390
+ import_logging58.logger.debug("get_credential_schema: starting", { correlationId, credential_type });
43234
43391
  try {
43235
43392
  const [rows, nodes] = await Promise.all([fetchSchemaRows(credential_type), fetchCompatibleNodes(credential_type)]);
43236
43393
  if (rows.length === 0)
43237
43394
  return handleUnknownType(credential_type, correlationId);
43238
43395
  return buildSchemaResponse(credential_type, rows, nodes, correlationId, startTime);
43239
43396
  } catch (error) {
43240
- import_logging57.logger.error("get_credential_schema: unexpected error", { correlationId, error });
43397
+ import_logging58.logger.error("get_credential_schema: unexpected error", { correlationId, error });
43241
43398
  const originalError = error instanceof Error ? error : new Error(String(error));
43242
43399
  if (isDbConfigError(originalError))
43243
43400
  return makeDbNotConfiguredResponse();
@@ -43286,7 +43443,7 @@ Example usage:
43286
43443
  };
43287
43444
 
43288
43445
  // dist/mcp/tools/handlers/create-credential.js
43289
- var import_logging58 = __toESM(require_logging(), 1);
43446
+ var import_logging59 = __toESM(require_logging(), 1);
43290
43447
  init_validatorPostgresClient();
43291
43448
  var DEFAULT_TIMEOUT_MS2 = 1e4;
43292
43449
  var FIELDS_SQL = `
@@ -43352,11 +43509,11 @@ function buildCreateError(error, correlationId) {
43352
43509
  const statusCode = error?.statusCode;
43353
43510
  const message = error instanceof Error ? error.message : String(error);
43354
43511
  if (statusCode === 401 || statusCode === 403) {
43355
- import_logging58.logger.warn("create_credential: auth error", { correlationId, statusCode });
43512
+ import_logging59.logger.warn("create_credential: auth error", { correlationId, statusCode });
43356
43513
  const data = { success: false, error: "AUTH_ERROR", message: "Authentication failed. Check N8N_API_KEY." };
43357
43514
  return toMCPResponse(createSuccessResponse(data, correlationId, { duration_ms: 0 }));
43358
43515
  }
43359
- import_logging58.logger.error("create_credential: unexpected error", { correlationId, error });
43516
+ import_logging59.logger.error("create_credential: unexpected error", { correlationId, error });
43360
43517
  return toMCPResponse(createInternalError(correlationId, error instanceof Error ? error : new Error(message)));
43361
43518
  }
43362
43519
  function buildExistsResponse(existing, correlationId) {
@@ -43376,7 +43533,7 @@ async function handleCreateCredential(args) {
43376
43533
  const correlationId = generateCorrelationId();
43377
43534
  const startTime = performance.now();
43378
43535
  const { credential_type, name, data } = args;
43379
- import_logging58.logger.debug("create_credential: starting", { correlationId, credential_type, name });
43536
+ import_logging59.logger.debug("create_credential: starting", { correlationId, credential_type, name });
43380
43537
  try {
43381
43538
  const fields = await fetchCredentialFields(credential_type);
43382
43539
  if (fields.length === 0)
@@ -43387,13 +43544,13 @@ async function handleCreateCredential(args) {
43387
43544
  const config3 = buildApiConfig15();
43388
43545
  const existing = await findExistingCredential(config3, credential_type, name);
43389
43546
  if (existing) {
43390
- import_logging58.logger.warn("create_credential: duplicate blocked", { correlationId, existing_id: existing.id, credential_type, name });
43547
+ import_logging59.logger.warn("create_credential: duplicate blocked", { correlationId, existing_id: existing.id, credential_type, name });
43391
43548
  return buildExistsResponse(existing, correlationId);
43392
43549
  }
43393
43550
  const result = await createCredential(config3, { name, type: credential_type, data });
43394
43551
  clearCredentialCache();
43395
43552
  const duration_ms = Math.round(performance.now() - startTime);
43396
- import_logging58.logger.info("create_credential: created", { correlationId, id: result.id, credential_type, name });
43553
+ import_logging59.logger.info("create_credential: created", { correlationId, id: result.id, credential_type, name });
43397
43554
  return buildCreateSuccessResponse(result, correlationId, duration_ms);
43398
43555
  } catch (error) {
43399
43556
  return buildCreateError(error, correlationId);
@@ -43445,7 +43602,7 @@ Example usage:
43445
43602
 
43446
43603
  // dist/mcp/tools/handlers/test-credential.js
43447
43604
  var net = __toESM(require("net"), 1);
43448
- var import_logging59 = __toESM(require_logging(), 1);
43605
+ var import_logging60 = __toESM(require_logging(), 1);
43449
43606
  var PROBE_TIMEOUT_MS = 5e3;
43450
43607
  var RATE_LIMIT_MS = 3e4;
43451
43608
  var lastTestTimestamps = /* @__PURE__ */ new Map();
@@ -43625,7 +43782,7 @@ function buildProbeError(error, correlationId) {
43625
43782
  const data = { supported: true, valid: false, message: "Credential not found. Check the credential ID." };
43626
43783
  return toMCPResponse(createSuccessResponse(data, correlationId, { duration_ms: 0 }));
43627
43784
  }
43628
- import_logging59.logger.error("test_credential: unexpected error", { correlationId, error });
43785
+ import_logging60.logger.error("test_credential: unexpected error", { correlationId, error });
43629
43786
  return toMCPResponse(createInternalError(correlationId, error instanceof Error ? error : new Error(String(error))));
43630
43787
  }
43631
43788
  async function handleTestCredential(args) {
@@ -43641,7 +43798,7 @@ async function handleTestCredential(args) {
43641
43798
  recordTestTimestamp(credential_id);
43642
43799
  try {
43643
43800
  const n8nResult = await testCredentialViaN8n(config3, credential_id, credential.name, credential.type, credential.data, restCreds);
43644
- import_logging59.logger.info("test_credential: n8n built-in test", {
43801
+ import_logging60.logger.info("test_credential: n8n built-in test", {
43645
43802
  correlationId,
43646
43803
  type: credential.type,
43647
43804
  valid: n8nResult.valid
@@ -43649,9 +43806,9 @@ async function handleTestCredential(args) {
43649
43806
  return buildProbeResponse(n8nResult, correlationId);
43650
43807
  } catch (n8nTestError) {
43651
43808
  if (n8nTestError?.code === "NEEDS_N8N_LOGIN") {
43652
- import_logging59.logger.debug("test_credential: n8n test unavailable, falling back to HTTP probes");
43809
+ import_logging60.logger.debug("test_credential: n8n test unavailable, falling back to HTTP probes");
43653
43810
  } else {
43654
- import_logging59.logger.warn("test_credential: n8n test failed, falling back to HTTP probes", {
43811
+ import_logging60.logger.warn("test_credential: n8n test failed, falling back to HTTP probes", {
43655
43812
  error: n8nTestError instanceof Error ? n8nTestError.message : String(n8nTestError)
43656
43813
  });
43657
43814
  }
@@ -43661,10 +43818,10 @@ async function handleTestCredential(args) {
43661
43818
  return buildUnsupportedResponse(credential.type, correlationId);
43662
43819
  const hasBlankValues = Object.values(credential.data).some((v) => typeof v === "string" && v.includes("__n8n_BLANK_VALUE_"));
43663
43820
  if (hasBlankValues) {
43664
- import_logging59.logger.warn("test_credential: credential data contains encrypted placeholders, probe may be unreliable");
43821
+ import_logging60.logger.warn("test_credential: credential data contains encrypted placeholders, probe may be unreliable");
43665
43822
  }
43666
43823
  const result = await probe(credential.data);
43667
- import_logging59.logger.info("test_credential: HTTP probe fallback", {
43824
+ import_logging60.logger.info("test_credential: HTTP probe fallback", {
43668
43825
  correlationId,
43669
43826
  type: credential.type,
43670
43827
  valid: result.valid,
@@ -43718,7 +43875,7 @@ Use list_credentials to find credential IDs.`,
43718
43875
  };
43719
43876
 
43720
43877
  // dist/mcp/tools/handlers/update-credential.js
43721
- var import_logging60 = __toESM(require_logging(), 1);
43878
+ var import_logging61 = __toESM(require_logging(), 1);
43722
43879
  var DEFAULT_TIMEOUT_MS3 = 1e4;
43723
43880
  function buildApiConfig17() {
43724
43881
  return {
@@ -43742,16 +43899,16 @@ function buildUpdateError(error, correlationId) {
43742
43899
  const statusCode = error?.statusCode;
43743
43900
  const message = error instanceof Error ? error.message : String(error);
43744
43901
  if (statusCode === 404) {
43745
- import_logging60.logger.warn("update_credential: not found", { correlationId, statusCode });
43902
+ import_logging61.logger.warn("update_credential: not found", { correlationId, statusCode });
43746
43903
  const data = { success: false, error: "NOT_FOUND", message: "Credential not found. Use list_credentials to find valid IDs." };
43747
43904
  return toMCPResponse(createSuccessResponse(data, correlationId, { duration_ms: 0 }));
43748
43905
  }
43749
43906
  if (statusCode === 401 || statusCode === 403) {
43750
- import_logging60.logger.warn("update_credential: auth error", { correlationId, statusCode });
43907
+ import_logging61.logger.warn("update_credential: auth error", { correlationId, statusCode });
43751
43908
  const data = { success: false, error: "AUTH_ERROR", message: "Authentication failed. Check N8N_API_KEY." };
43752
43909
  return toMCPResponse(createSuccessResponse(data, correlationId, { duration_ms: 0 }));
43753
43910
  }
43754
- import_logging60.logger.error("update_credential: unexpected error", { correlationId, error });
43911
+ import_logging61.logger.error("update_credential: unexpected error", { correlationId, error });
43755
43912
  return toMCPResponse(createInternalError(correlationId, error instanceof Error ? error : new Error(message)));
43756
43913
  }
43757
43914
  async function buildUpdatePayload(config3, args) {
@@ -43766,9 +43923,9 @@ function buildUpdateSuccessResponse2(result, correlationId, duration_ms) {
43766
43923
  async function handleUpdateCredential(args) {
43767
43924
  const correlationId = generateCorrelationId();
43768
43925
  const startTime = performance.now();
43769
- import_logging60.logger.debug("update_credential: starting", { correlationId, credential_id: args.credential_id });
43926
+ import_logging61.logger.debug("update_credential: starting", { correlationId, credential_id: args.credential_id });
43770
43927
  if (args.data && Object.keys(args.data).length > 0) {
43771
- import_logging60.logger.warn("update_credential: rejected data write attempt", { correlationId, credential_id: args.credential_id });
43928
+ import_logging61.logger.warn("update_credential: rejected data write attempt", { correlationId, credential_id: args.credential_id });
43772
43929
  const data = {
43773
43930
  success: false,
43774
43931
  error: "DATA_WRITE_DENIED",
@@ -43789,7 +43946,7 @@ async function handleUpdateCredential(args) {
43789
43946
  const payload = await buildUpdatePayload(config3, { ...args, data: void 0 });
43790
43947
  const result = await updateCredential(config3, args.credential_id, payload);
43791
43948
  invalidate();
43792
- import_logging60.logger.info("update_credential: updated (name only)", { correlationId, id: result.id });
43949
+ import_logging61.logger.info("update_credential: updated (name only)", { correlationId, id: result.id });
43793
43950
  return buildUpdateSuccessResponse2(result, correlationId, Math.round(performance.now() - startTime));
43794
43951
  } catch (error) {
43795
43952
  return buildUpdateError(error, correlationId);
@@ -43824,7 +43981,7 @@ On not found: returns NOT_FOUND error with guidance.`,
43824
43981
  };
43825
43982
 
43826
43983
  // dist/mcp/tools/handlers/delete-credential.js
43827
- var import_logging61 = __toESM(require_logging(), 1);
43984
+ var import_logging62 = __toESM(require_logging(), 1);
43828
43985
  var DEFAULT_TIMEOUT_MS4 = 1e4;
43829
43986
  var MAX_WORKFLOWS_TO_SCAN = 100;
43830
43987
  function buildApiConfig18() {
@@ -43883,18 +44040,18 @@ function buildDeleteError(error, correlationId) {
43883
44040
  const statusCode = error?.statusCode;
43884
44041
  const message = error instanceof Error ? error.message : String(error);
43885
44042
  if (statusCode === 401 || statusCode === 403) {
43886
- import_logging61.logger.warn("delete_credential: auth error", { correlationId, statusCode });
44043
+ import_logging62.logger.warn("delete_credential: auth error", { correlationId, statusCode });
43887
44044
  const data = { success: false, error: "AUTH_ERROR", message: "Authentication failed. Check N8N_API_KEY." };
43888
44045
  return toMCPResponse(createSuccessResponse(data, correlationId, { duration_ms: 0 }));
43889
44046
  }
43890
- import_logging61.logger.error("delete_credential: unexpected error", { correlationId, error });
44047
+ import_logging62.logger.error("delete_credential: unexpected error", { correlationId, error });
43891
44048
  return toMCPResponse(createInternalError(correlationId, error instanceof Error ? error : new Error(message)));
43892
44049
  }
43893
44050
  async function checkAndWarnDependents(config3, credential_id, correlationId) {
43894
44051
  const dependentWorkflows = await findDependentWorkflows(config3, credential_id);
43895
44052
  if (dependentWorkflows.length === 0)
43896
44053
  return null;
43897
- import_logging61.logger.warn("delete_credential: dependent workflows found", { correlationId, credential_id, count: dependentWorkflows.length });
44054
+ import_logging62.logger.warn("delete_credential: dependent workflows found", { correlationId, credential_id, count: dependentWorkflows.length });
43898
44055
  return buildDependentWarningResponse(credential_id, dependentWorkflows, correlationId);
43899
44056
  }
43900
44057
  async function executeDelete(config3, credential_id, force, correlationId, startTime) {
@@ -43905,14 +44062,14 @@ async function executeDelete(config3, credential_id, force, correlationId, start
43905
44062
  }
43906
44063
  await deleteCredential(config3, credential_id);
43907
44064
  invalidate();
43908
- import_logging61.logger.info("delete_credential: deleted", { correlationId, credential_id, force });
44065
+ import_logging62.logger.info("delete_credential: deleted", { correlationId, credential_id, force });
43909
44066
  return buildDeleteSuccessResponse(credential_id, correlationId, Math.round(performance.now() - startTime));
43910
44067
  }
43911
44068
  async function handleDeleteCredential(args) {
43912
44069
  const correlationId = generateCorrelationId();
43913
44070
  const startTime = performance.now();
43914
44071
  const { credential_id, force = false } = args;
43915
- import_logging61.logger.debug("delete_credential: starting", { correlationId, credential_id, force });
44072
+ import_logging62.logger.debug("delete_credential: starting", { correlationId, credential_id, force });
43916
44073
  try {
43917
44074
  return await executeDelete(buildApiConfig18(), credential_id, force, correlationId, startTime);
43918
44075
  } catch (error) {
@@ -43957,12 +44114,12 @@ On auth error: returns AUTH_ERROR with guidance.`,
43957
44114
  };
43958
44115
 
43959
44116
  // dist/mcp/tools/handlers/collect-config.js
43960
- var import_logging63 = __toESM(require_logging(), 1);
44117
+ var import_logging64 = __toESM(require_logging(), 1);
43961
44118
  init_validatorPostgresClient();
43962
- var import_retry8 = __toESM(require_retryUtils(), 1);
44119
+ var import_retry9 = __toESM(require_retryUtils(), 1);
43963
44120
 
43964
44121
  // dist/mcp/session/config-cache.js
43965
- var import_logging62 = __toESM(require_logging(), 1);
44122
+ var import_logging63 = __toESM(require_logging(), 1);
43966
44123
  var CONFIG_CACHE_TTL_MS = 30 * 60 * 1e3;
43967
44124
  var CONFIG_CACHE_MAX_ENTRIES = 500;
43968
44125
  var cacheState2 = null;
@@ -44005,12 +44162,12 @@ function set(key, value) {
44005
44162
  stored_at: Date.now(),
44006
44163
  expires_at: Date.now() + CONFIG_CACHE_TTL_MS
44007
44164
  });
44008
- import_logging62.logger.debug("config-cache: stored value", { key });
44165
+ import_logging63.logger.debug("config-cache: stored value", { key });
44009
44166
  }
44010
44167
  function clearConfigCache() {
44011
44168
  cacheState2 = null;
44012
44169
  warming = null;
44013
- import_logging62.logger.debug("config-cache: cleared");
44170
+ import_logging63.logger.debug("config-cache: cleared");
44014
44171
  }
44015
44172
  function getSuggestion(configType, nodeType, parameterName) {
44016
44173
  const serviceId = extractServiceId(nodeType);
@@ -44142,7 +44299,7 @@ function buildConfigValues(answered) {
44142
44299
  return result;
44143
44300
  }
44144
44301
  async function markGapsResolved(gapType, nodeType, notes) {
44145
- await (0, import_retry8.retryDbQuery)(() => validatorQuery(RESOLVE_GAPS_SQL, [gapType, nodeType, notes]), 3, "collect_config_resolve_gaps");
44302
+ await (0, import_retry9.retryDbQuery)(() => validatorQuery(RESOLVE_GAPS_SQL, [gapType, nodeType, notes]), 3, "collect_config_resolve_gaps");
44146
44303
  }
44147
44304
  async function resolveOneGap(req) {
44148
44305
  const gapType = CATEGORY_TO_GAP_TYPE[req.configType];
@@ -44151,7 +44308,7 @@ async function resolveOneGap(req) {
44151
44308
  try {
44152
44309
  await markGapsResolved(gapType, req.nodeType, `Resolved via collect_config: ${req.parameterName}`);
44153
44310
  } catch (error) {
44154
- import_logging63.logger.warn("collect_config: gap resolution failed (non-fatal)", {
44311
+ import_logging64.logger.warn("collect_config: gap resolution failed (non-fatal)", {
44155
44312
  nodeType: req.nodeType,
44156
44313
  gapType,
44157
44314
  error: error instanceof Error ? error.message : String(error)
@@ -44193,14 +44350,14 @@ async function executeCollect(args) {
44193
44350
  async function handleCollectConfig(args) {
44194
44351
  const correlationId = generateCorrelationId();
44195
44352
  const startTime = performance.now();
44196
- import_logging63.logger.debug("collect_config: starting", { correlationId });
44353
+ import_logging64.logger.debug("collect_config: starting", { correlationId });
44197
44354
  try {
44198
44355
  const { output, logMeta } = await executeCollect(args);
44199
44356
  const duration_ms = Math.round(performance.now() - startTime);
44200
- import_logging63.logger.info("collect_config: completed", { correlationId, ...logMeta });
44357
+ import_logging64.logger.info("collect_config: completed", { correlationId, ...logMeta });
44201
44358
  return toMCPResponse(createSuccessResponse(output, correlationId, { duration_ms }));
44202
44359
  } catch (error) {
44203
- import_logging63.logger.error("collect_config: failed", { correlationId, error });
44360
+ import_logging64.logger.error("collect_config: failed", { correlationId, error });
44204
44361
  return toMCPResponse(createInternalError(correlationId, error instanceof Error ? error : new Error(String(error))));
44205
44362
  }
44206
44363
  }
@@ -44644,7 +44801,7 @@ function redactMCPResponse(response) {
44644
44801
 
44645
44802
  // dist/mcp/server-lifecycle.js
44646
44803
  init_validatorPostgresClient();
44647
- var import_logging64 = __toESM(require_logging(), 1);
44804
+ var import_logging65 = __toESM(require_logging(), 1);
44648
44805
  var defaultDeps = {
44649
44806
  shutdownPool: shutdownValidatorPool,
44650
44807
  clearCache: clearCredentialCache,
@@ -44657,7 +44814,7 @@ async function runCleanup(serverName, deps) {
44657
44814
  deps.clearCache();
44658
44815
  deps.clearConfigCache?.();
44659
44816
  } catch (err) {
44660
- import_logging64.logger.error(`[${serverName}] Error during shutdown:`, err);
44817
+ import_logging65.logger.error(`[${serverName}] Error during shutdown:`, err);
44661
44818
  }
44662
44819
  }
44663
44820
  function createShutdownHandler(serverName, deps = defaultDeps) {
@@ -44666,7 +44823,7 @@ function createShutdownHandler(serverName, deps = defaultDeps) {
44666
44823
  if (isShuttingDown)
44667
44824
  return;
44668
44825
  isShuttingDown = true;
44669
- import_logging64.logger.info(`[${serverName}] Received ${signal}, shutting down...`);
44826
+ import_logging65.logger.info(`[${serverName}] Received ${signal}, shutting down...`);
44670
44827
  await runCleanup(serverName, deps);
44671
44828
  process.exit(0);
44672
44829
  };
@@ -44679,7 +44836,7 @@ function registerShutdownHandlers(serverName, deps) {
44679
44836
  process.stdin.on("end", () => void shutdown("stdin-close"));
44680
44837
  process.stdin.on("close", () => void shutdown("stdin-close"));
44681
44838
  process.on("exit", (code) => {
44682
- import_logging64.logger.debug(`[${serverName}] Process exiting (code ${code})`);
44839
+ import_logging65.logger.debug(`[${serverName}] Process exiting (code ${code})`);
44683
44840
  });
44684
44841
  }
44685
44842
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@path58/p58-n8n",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "The smartest and fastest n8n MCP server — validate, fix, and discover workflows inside your LLM",
5
5
  "keywords": [
6
6
  "mcp",