@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 +1 -1
- package/CHANGELOG.md +22 -0
- package/dist/mcp/server.bundle.cjs +243 -86
- package/package.json +1 -1
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.
|
|
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 =
|
|
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
|
|
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.
|
|
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
|
|
41487
|
-
var
|
|
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
|
|
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
|
|
41550
|
-
const
|
|
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,
|
|
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
|
-
|
|
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] = {
|
|
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].
|
|
42465
|
-
result[conn.from].
|
|
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
|
-
|
|
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
|
|
42490
|
-
const
|
|
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
|
-
|
|
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
|
|
42500
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
43809
|
+
import_logging60.logger.debug("test_credential: n8n test unavailable, falling back to HTTP probes");
|
|
43653
43810
|
} else {
|
|
43654
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
44117
|
+
var import_logging64 = __toESM(require_logging(), 1);
|
|
43961
44118
|
init_validatorPostgresClient();
|
|
43962
|
-
var
|
|
44119
|
+
var import_retry9 = __toESM(require_retryUtils(), 1);
|
|
43963
44120
|
|
|
43964
44121
|
// dist/mcp/session/config-cache.js
|
|
43965
|
-
var
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
44357
|
+
import_logging64.logger.info("collect_config: completed", { correlationId, ...logMeta });
|
|
44201
44358
|
return toMCPResponse(createSuccessResponse(output, correlationId, { duration_ms }));
|
|
44202
44359
|
} catch (error) {
|
|
44203
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
44839
|
+
import_logging65.logger.debug(`[${serverName}] Process exiting (code ${code})`);
|
|
44683
44840
|
});
|
|
44684
44841
|
}
|
|
44685
44842
|
|