Merge pull request #181 from czlonkowski/update-n8n-deps-20250904

chore: update n8n dependencies to v1.109.2 and bump to v2.10.8
This commit is contained in:
Romuald Członkowski
2025-09-04 12:00:58 +02:00
committed by GitHub
7 changed files with 17824 additions and 22848 deletions

View File

@@ -2,11 +2,11 @@
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![GitHub stars](https://img.shields.io/github/stars/czlonkowski/n8n-mcp?style=social)](https://github.com/czlonkowski/n8n-mcp) [![GitHub stars](https://img.shields.io/github/stars/czlonkowski/n8n-mcp?style=social)](https://github.com/czlonkowski/n8n-mcp)
[![Version](https://img.shields.io/badge/version-2.10.5-blue.svg)](https://github.com/czlonkowski/n8n-mcp) [![Version](https://img.shields.io/badge/version-2.10.8-blue.svg)](https://github.com/czlonkowski/n8n-mcp)
[![npm version](https://img.shields.io/npm/v/n8n-mcp.svg)](https://www.npmjs.com/package/n8n-mcp) [![npm version](https://img.shields.io/npm/v/n8n-mcp.svg)](https://www.npmjs.com/package/n8n-mcp)
[![codecov](https://codecov.io/gh/czlonkowski/n8n-mcp/graph/badge.svg?token=YOUR_TOKEN)](https://codecov.io/gh/czlonkowski/n8n-mcp) [![codecov](https://codecov.io/gh/czlonkowski/n8n-mcp/graph/badge.svg?token=YOUR_TOKEN)](https://codecov.io/gh/czlonkowski/n8n-mcp)
[![Tests](https://img.shields.io/badge/tests-1728%20passing-brightgreen.svg)](https://github.com/czlonkowski/n8n-mcp/actions) [![Tests](https://img.shields.io/badge/tests-1728%20passing-brightgreen.svg)](https://github.com/czlonkowski/n8n-mcp/actions)
[![n8n version](https://img.shields.io/badge/n8n-^1.107.4-orange.svg)](https://github.com/n8n-io/n8n) [![n8n version](https://img.shields.io/badge/n8n-^1.109.2-orange.svg)](https://github.com/n8n-io/n8n)
[![Docker](https://img.shields.io/badge/docker-ghcr.io%2Fczlonkowski%2Fn8n--mcp-green.svg)](https://github.com/czlonkowski/n8n-mcp/pkgs/container/n8n-mcp) [![Docker](https://img.shields.io/badge/docker-ghcr.io%2Fczlonkowski%2Fn8n--mcp-green.svg)](https://github.com/czlonkowski/n8n-mcp/pkgs/container/n8n-mcp)
[![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/deploy/n8n-mcp?referralCode=n8n-mcp) [![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/deploy/n8n-mcp?referralCode=n8n-mcp)

Binary file not shown.

View File

@@ -7,6 +7,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [2.10.8] - 2025-09-04
### Updated
- **n8n Dependencies**: Updated to latest versions for compatibility and new features
- n8n: 1.107.4 → 1.109.2
- @n8n/n8n-nodes-langchain: 1.106.2 → 1.109.1
- n8n-nodes-base: 1.106.3 → 1.108.0 (via dependencies)
- **Node Database**: Rebuilt with 535 nodes from updated n8n packages
- **Node.js Compatibility**: Optimized for Node.js v22.17.0 LTS
- Enhanced better-sqlite3 native binary compatibility
- Fixed SQL.js fallback mode for environments without native binaries
- **CI/CD Improvements**: Fixed Rollup native module compatibility for GitHub Actions
- Added explicit platform-specific rollup binaries for cross-platform builds
- Resolved npm ci failures in Linux CI environment
- Fixed package-lock.json synchronization issues
- **Platform Support**: Enhanced cross-platform deployment compatibility
- macOS ARM64 and Linux x64 platform binaries included
- Improved npm package distribution with proper dependency resolution
- All 1,728+ tests passing with updated dependencies
### Fixed
- **CI/CD Pipeline**: Resolved test failures in GitHub Actions
- Fixed pyodide version conflicts between langchain dependencies
- Regenerated package-lock.json with proper dependency resolution
- Fixed Rollup native module loading in Linux CI environment
- **Database Compatibility**: Enhanced SQL.js fallback reliability
- Improved parameter binding and state management
- Fixed statement cleanup to prevent memory leaks
- **Deployment Reliability**: Better handling of platform-specific dependencies
- npm ci now works consistently across development and CI environments
## [2.10.5] - 2025-08-20 ## [2.10.5] - 2025-08-20
### Updated ### Updated

40470
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "n8n-mcp", "name": "n8n-mcp",
"version": "2.10.5", "version": "2.10.8",
"description": "Integration between n8n workflow automation and Model Context Protocol (MCP)", "description": "Integration between n8n workflow automation and Model Context Protocol (MCP)",
"main": "dist/index.js", "main": "dist/index.js",
"bin": { "bin": {
@@ -128,16 +128,18 @@
}, },
"dependencies": { "dependencies": {
"@modelcontextprotocol/sdk": "^1.13.2", "@modelcontextprotocol/sdk": "^1.13.2",
"@n8n/n8n-nodes-langchain": "^1.106.2", "@n8n/n8n-nodes-langchain": "^1.108.1",
"dotenv": "^16.5.0", "dotenv": "^16.5.0",
"express": "^5.1.0", "express": "^5.1.0",
"n8n": "^1.107.4", "n8n": "^1.109.2",
"n8n-core": "^1.106.2", "n8n-core": "^1.108.0",
"n8n-workflow": "^1.104.1", "n8n-workflow": "^1.106.0",
"sql.js": "^1.13.0", "sql.js": "^1.13.0",
"uuid": "^10.0.0" "uuid": "^10.0.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"@rollup/rollup-darwin-arm64": "^4.50.0",
"@rollup/rollup-linux-x64-gnu": "^4.50.0",
"better-sqlite3": "^11.10.0" "better-sqlite3": "^11.10.0"
} }
} }

View File

@@ -376,52 +376,71 @@ class SQLJSStatement implements PreparedStatement {
constructor(private stmt: any, private onModify: () => void) {} constructor(private stmt: any, private onModify: () => void) {}
run(...params: any[]): RunResult { run(...params: any[]): RunResult {
if (params.length > 0) { try {
this.bindParams(params); if (params.length > 0) {
this.stmt.bind(this.boundParams); this.bindParams(params);
if (this.boundParams) {
this.stmt.bind(this.boundParams);
}
}
this.stmt.run();
this.onModify();
// sql.js doesn't provide changes/lastInsertRowid easily
return {
changes: 1, // Assume success means 1 change
lastInsertRowid: 0
};
} catch (error) {
this.stmt.reset();
throw error;
} }
this.stmt.run();
this.onModify();
// sql.js doesn't provide changes/lastInsertRowid easily
return {
changes: 0,
lastInsertRowid: 0
};
} }
get(...params: any[]): any { get(...params: any[]): any {
if (params.length > 0) { try {
this.bindParams(params); if (params.length > 0) {
} this.bindParams(params);
if (this.boundParams) {
this.stmt.bind(this.boundParams); this.stmt.bind(this.boundParams);
}
if (this.stmt.step()) { }
const result = this.stmt.getAsObject();
if (this.stmt.step()) {
const result = this.stmt.getAsObject();
this.stmt.reset();
return this.convertIntegerColumns(result);
}
this.stmt.reset(); this.stmt.reset();
return this.convertIntegerColumns(result); return undefined;
} catch (error) {
this.stmt.reset();
throw error;
} }
this.stmt.reset();
return undefined;
} }
all(...params: any[]): any[] { all(...params: any[]): any[] {
if (params.length > 0) { try {
this.bindParams(params); if (params.length > 0) {
this.bindParams(params);
if (this.boundParams) {
this.stmt.bind(this.boundParams);
}
}
const results: any[] = [];
while (this.stmt.step()) {
results.push(this.convertIntegerColumns(this.stmt.getAsObject()));
}
this.stmt.reset();
return results;
} catch (error) {
this.stmt.reset();
throw error;
} }
this.stmt.bind(this.boundParams);
const results: any[] = [];
while (this.stmt.step()) {
results.push(this.convertIntegerColumns(this.stmt.getAsObject()));
}
this.stmt.reset();
return results;
} }
iterate(...params: any[]): IterableIterator<any> { iterate(...params: any[]): IterableIterator<any> {
@@ -455,12 +474,18 @@ class SQLJSStatement implements PreparedStatement {
} }
private bindParams(params: any[]): void { private bindParams(params: any[]): void {
if (params.length === 1 && typeof params[0] === 'object' && !Array.isArray(params[0])) { if (params.length === 0) {
this.boundParams = null;
return;
}
if (params.length === 1 && typeof params[0] === 'object' && !Array.isArray(params[0]) && params[0] !== null) {
// Named parameters passed as object // Named parameters passed as object
this.boundParams = params[0]; this.boundParams = params[0];
} else { } else {
// Positional parameters - sql.js uses array for positional // Positional parameters - sql.js uses array for positional
this.boundParams = params; // Filter out undefined values that might cause issues
this.boundParams = params.map(p => p === undefined ? null : p);
} }
} }

View File

@@ -5,7 +5,7 @@
*/ */
import { createDatabaseAdapter } from '../database/database-adapter'; import { createDatabaseAdapter } from '../database/database-adapter';
import { N8nNodeLoader } from '../loaders/node-loader'; import { N8nNodeLoader } from '../loaders/node-loader';
import { NodeParser } from '../parsers/node-parser'; import { NodeParser, ParsedNode } from '../parsers/node-parser';
import { DocsMapper } from '../mappers/docs-mapper'; import { DocsMapper } from '../mappers/docs-mapper';
import { NodeRepository } from '../database/node-repository'; import { NodeRepository } from '../database/node-repository';
import { TemplateSanitizer } from '../utils/template-sanitizer'; import { TemplateSanitizer } from '../utils/template-sanitizer';
@@ -46,7 +46,10 @@ async function rebuild() {
withDocs: 0 withDocs: 0
}; };
// Process each node // Process each node (documentation fetching must be outside transaction due to async)
console.log('🔄 Processing nodes...');
const processedNodes: Array<{ parsed: ParsedNode; docs: string | undefined; nodeName: string }> = [];
for (const { packageName, nodeName, NodeClass } of nodes) { for (const { packageName, nodeName, NodeClass } of nodes) {
try { try {
// Parse node // Parse node
@@ -54,15 +57,34 @@ async function rebuild() {
// Validate parsed data // Validate parsed data
if (!parsed.nodeType || !parsed.displayName) { if (!parsed.nodeType || !parsed.displayName) {
throw new Error('Missing required fields'); throw new Error(`Missing required fields - nodeType: ${parsed.nodeType}, displayName: ${parsed.displayName}, packageName: ${parsed.packageName}`);
}
// Additional validation for required fields
if (!parsed.packageName) {
throw new Error(`Missing packageName for node ${nodeName}`);
} }
// Get documentation // Get documentation
const docs = await mapper.fetchDocumentation(parsed.nodeType); const docs = await mapper.fetchDocumentation(parsed.nodeType);
parsed.documentation = docs || undefined; parsed.documentation = docs || undefined;
// Save to database processedNodes.push({ parsed, docs: docs || undefined, nodeName });
} catch (error) {
stats.failed++;
const errorMessage = (error as Error).message;
console.error(`❌ Failed to process ${nodeName}: ${errorMessage}`);
}
}
// Now save all processed nodes to database
console.log(`\n💾 Saving ${processedNodes.length} processed nodes to database...`);
let saved = 0;
for (const { parsed, docs, nodeName } of processedNodes) {
try {
repository.saveNode(parsed); repository.saveNode(parsed);
saved++;
// Update statistics // Update statistics
stats.successful++; stats.successful++;
@@ -76,13 +98,28 @@ async function rebuild() {
console.log(`${parsed.nodeType} [Props: ${parsed.properties.length}, Ops: ${parsed.operations.length}]`); console.log(`${parsed.nodeType} [Props: ${parsed.properties.length}, Ops: ${parsed.operations.length}]`);
} catch (error) { } catch (error) {
stats.failed++; stats.failed++;
console.error(`❌ Failed to process ${nodeName}: ${(error as Error).message}`); const errorMessage = (error as Error).message;
console.error(`❌ Failed to save ${nodeName}: ${errorMessage}`);
} }
} }
console.log(`💾 Save completed: ${saved} nodes saved successfully`);
// Validation check // Validation check
console.log('\n🔍 Running validation checks...'); console.log('\n🔍 Running validation checks...');
const validationResults = validateDatabase(repository); try {
const validationResults = validateDatabase(repository);
if (!validationResults.passed) {
console.log('⚠️ Validation Issues:');
validationResults.issues.forEach(issue => console.log(` - ${issue}`));
} else {
console.log('✅ All validation checks passed');
}
} catch (validationError) {
console.error('❌ Validation failed:', (validationError as Error).message);
console.log('⚠️ Skipping validation due to database compatibility issues');
}
// Summary // Summary
console.log('\n📊 Summary:'); console.log('\n📊 Summary:');
@@ -96,11 +133,6 @@ async function rebuild() {
console.log(` With Operations: ${stats.withOperations}`); console.log(` With Operations: ${stats.withOperations}`);
console.log(` With Documentation: ${stats.withDocs}`); console.log(` With Documentation: ${stats.withDocs}`);
if (!validationResults.passed) {
console.log('\n⚠ Validation Issues:');
validationResults.issues.forEach(issue => console.log(` - ${issue}`));
}
// Sanitize templates if they exist // Sanitize templates if they exist
console.log('\n🧹 Checking for templates to sanitize...'); console.log('\n🧹 Checking for templates to sanitize...');
const templateCount = db.prepare('SELECT COUNT(*) as count FROM templates').get() as { count: number }; const templateCount = db.prepare('SELECT COUNT(*) as count FROM templates').get() as { count: number };