fix: resolve WASM file loading issue for npx execution (closes #31)
- Enhanced database adapter to support multiple WASM file resolution strategies - Added require.resolve() for reliable package location in npm environments - Made better-sqlite3 an optional dependency - Improved error handling with clear messages - Updated version to 2.7.13 - Updated CHANGELOG and README badges
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
[](https://opensource.org/licenses/MIT)
|
[](https://opensource.org/licenses/MIT)
|
||||||
[](https://github.com/czlonkowski/n8n-mcp)
|
[](https://github.com/czlonkowski/n8n-mcp)
|
||||||
[](https://github.com/czlonkowski/n8n-mcp)
|
[](https://github.com/czlonkowski/n8n-mcp)
|
||||||
[](https://www.npmjs.com/package/n8n-mcp)
|
[](https://www.npmjs.com/package/n8n-mcp)
|
||||||
[](https://github.com/n8n-io/n8n)
|
[](https://github.com/n8n-io/n8n)
|
||||||
[](https://github.com/czlonkowski/n8n-mcp/pkgs/container/n8n-mcp)
|
[](https://github.com/czlonkowski/n8n-mcp/pkgs/container/n8n-mcp)
|
||||||
|
|||||||
BIN
data/nodes.db
BIN
data/nodes.db
Binary file not shown.
@@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [2.7.13] - 2025-07-11
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- **npx Execution**: Fixed WASM file resolution for sql.js when running via `npx n8n-mcp` (Issue #31)
|
||||||
|
- Enhanced WASM file locator to try multiple path resolution strategies
|
||||||
|
- Added `require.resolve()` for reliable package location in npm environments
|
||||||
|
- Made better-sqlite3 an optional dependency to prevent installation failures
|
||||||
|
- Improved error messages when sql.js fails to load
|
||||||
|
- The package now works correctly with `npx` without any manual configuration
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- **Database Adapter**: Improved path resolution for both local development and npm package contexts
|
||||||
|
- Supports various npm installation scenarios (global, local, npx cache)
|
||||||
|
- Better fallback handling for sql.js WebAssembly file loading
|
||||||
|
|
||||||
## [2.7.12] - 2025-07-10
|
## [2.7.12] - 2025-07-10
|
||||||
|
|
||||||
### Updated
|
### Updated
|
||||||
@@ -565,6 +580,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Basic n8n and MCP integration
|
- Basic n8n and MCP integration
|
||||||
- Core workflow automation features
|
- Core workflow automation features
|
||||||
|
|
||||||
|
[2.7.13]: https://github.com/czlonkowski/n8n-mcp/compare/v2.7.12...v2.7.13
|
||||||
[2.7.12]: https://github.com/czlonkowski/n8n-mcp/compare/v2.7.11...v2.7.12
|
[2.7.12]: https://github.com/czlonkowski/n8n-mcp/compare/v2.7.11...v2.7.12
|
||||||
[2.7.11]: https://github.com/czlonkowski/n8n-mcp/compare/v2.7.10...v2.7.11
|
[2.7.11]: https://github.com/czlonkowski/n8n-mcp/compare/v2.7.10...v2.7.11
|
||||||
[2.7.10]: https://github.com/czlonkowski/n8n-mcp/compare/v2.7.8...v2.7.10
|
[2.7.10]: https://github.com/czlonkowski/n8n-mcp/compare/v2.7.8...v2.7.10
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "n8n-mcp",
|
"name": "n8n-mcp",
|
||||||
"version": "2.7.12",
|
"version": "2.7.13",
|
||||||
"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": {
|
||||||
@@ -103,5 +103,8 @@
|
|||||||
"n8n-workflow": "^1.98.0",
|
"n8n-workflow": "^1.98.0",
|
||||||
"sql.js": "^1.13.0",
|
"sql.js": "^1.13.0",
|
||||||
"uuid": "^10.0.0"
|
"uuid": "^10.0.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"better-sqlite3": "^11.10.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "n8n-mcp-runtime",
|
"name": "n8n-mcp-runtime",
|
||||||
"version": "2.7.12",
|
"version": "2.7.13",
|
||||||
"description": "n8n MCP Server Runtime Dependencies Only",
|
"description": "n8n MCP Server Runtime Dependencies Only",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -15,5 +15,8 @@
|
|||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.0.0"
|
"node": ">=16.0.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"better-sqlite3": "^11.10.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ pkg.license = 'MIT';
|
|||||||
pkg.bugs = { url: 'https://github.com/czlonkowski/n8n-mcp/issues' };
|
pkg.bugs = { url: 'https://github.com/czlonkowski/n8n-mcp/issues' };
|
||||||
pkg.homepage = 'https://github.com/czlonkowski/n8n-mcp#readme';
|
pkg.homepage = 'https://github.com/czlonkowski/n8n-mcp#readme';
|
||||||
pkg.files = ['dist/**/*', 'data/nodes.db', '.env.example', 'README.md', 'LICENSE'];
|
pkg.files = ['dist/**/*', 'data/nodes.db', '.env.example', 'README.md', 'LICENSE'];
|
||||||
|
// Note: node_modules are automatically included for dependencies
|
||||||
delete pkg.private; // Remove private field so we can publish
|
delete pkg.private; // Remove private field so we can publish
|
||||||
require('fs').writeFileSync('./package.json', JSON.stringify(pkg, null, 2));
|
require('fs').writeFileSync('./package.json', JSON.stringify(pkg, null, 2));
|
||||||
"
|
"
|
||||||
|
|||||||
38
scripts/test-database-adapter.js
Executable file
38
scripts/test-database-adapter.js
Executable file
@@ -0,0 +1,38 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const { createDatabaseAdapter } = require('../dist/database/database-adapter');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
async function testDatabaseAdapter() {
|
||||||
|
console.log('Testing database adapter initialization...\n');
|
||||||
|
|
||||||
|
const dbPath = path.join(__dirname, '../data/nodes.db');
|
||||||
|
console.log('Database path:', dbPath);
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log('Creating database adapter...');
|
||||||
|
const adapter = await createDatabaseAdapter(dbPath);
|
||||||
|
|
||||||
|
console.log('\n✅ Database adapter created successfully!');
|
||||||
|
|
||||||
|
// Test a simple query
|
||||||
|
console.log('\nTesting database query...');
|
||||||
|
const stmt = adapter.prepare('SELECT COUNT(*) as count FROM nodes');
|
||||||
|
const result = stmt.get();
|
||||||
|
console.log(`✅ Database contains ${result.count} nodes`);
|
||||||
|
|
||||||
|
// Check FTS5 support
|
||||||
|
console.log('\nChecking FTS5 support...');
|
||||||
|
const hasFTS5 = adapter.checkFTS5Support();
|
||||||
|
console.log(`FTS5 support: ${hasFTS5 ? '✅ Available' : '❌ Not available'}`);
|
||||||
|
|
||||||
|
adapter.close();
|
||||||
|
console.log('\n✅ All tests passed!');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('\n❌ Error:', error.message);
|
||||||
|
console.error('Stack:', error.stack);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testDatabaseAdapter();
|
||||||
43
scripts/test-sqljs-fallback.js
Executable file
43
scripts/test-sqljs-fallback.js
Executable file
@@ -0,0 +1,43 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
// Force sql.js usage by temporarily hiding better-sqlite3
|
||||||
|
const Module = require('module');
|
||||||
|
const originalRequire = Module.prototype.require;
|
||||||
|
|
||||||
|
Module.prototype.require = function(id) {
|
||||||
|
if (id === 'better-sqlite3') {
|
||||||
|
throw new Error('Simulating better-sqlite3 not available (NODE_MODULE_VERSION mismatch)');
|
||||||
|
}
|
||||||
|
return originalRequire.apply(this, arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
const { createDatabaseAdapter } = require('../dist/database/database-adapter');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
async function testSqlJsFallback() {
|
||||||
|
console.log('Testing sql.js fallback...\n');
|
||||||
|
|
||||||
|
const dbPath = path.join(__dirname, '../data/nodes.db');
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log('Creating database adapter (better-sqlite3 disabled)...');
|
||||||
|
const adapter = await createDatabaseAdapter(dbPath);
|
||||||
|
|
||||||
|
console.log('\n✅ Database adapter created successfully with sql.js!');
|
||||||
|
|
||||||
|
// Test a simple query
|
||||||
|
console.log('\nTesting database query...');
|
||||||
|
const stmt = adapter.prepare('SELECT COUNT(*) as count FROM nodes');
|
||||||
|
const result = stmt.get();
|
||||||
|
console.log(`✅ Database contains ${result.count} nodes`);
|
||||||
|
|
||||||
|
adapter.close();
|
||||||
|
console.log('\n✅ sql.js fallback works correctly!');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('\n❌ Error:', error.message);
|
||||||
|
console.error('Stack:', error.stack);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testSqlJsFallback();
|
||||||
52
scripts/test-wasm-resolution.js
Executable file
52
scripts/test-wasm-resolution.js
Executable file
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
console.log('Testing WASM file resolution...\n');
|
||||||
|
|
||||||
|
// Show current environment
|
||||||
|
console.log('Current directory:', process.cwd());
|
||||||
|
console.log('Script directory:', __dirname);
|
||||||
|
console.log('Node version:', process.version);
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
// Test different path resolutions
|
||||||
|
const testPaths = [
|
||||||
|
// Local development path
|
||||||
|
path.join(__dirname, '../node_modules/sql.js/dist/sql-wasm.wasm'),
|
||||||
|
// When installed as npm package
|
||||||
|
path.join(__dirname, '../../sql.js/dist/sql-wasm.wasm'),
|
||||||
|
// Alternative npm package path
|
||||||
|
path.join(process.cwd(), 'node_modules/sql.js/dist/sql-wasm.wasm'),
|
||||||
|
];
|
||||||
|
|
||||||
|
console.log('Checking potential WASM file locations:');
|
||||||
|
testPaths.forEach((testPath, index) => {
|
||||||
|
const exists = fs.existsSync(testPath);
|
||||||
|
console.log(`${index + 1}. ${testPath}`);
|
||||||
|
console.log(` Exists: ${exists ? '✅' : '❌'}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Try require.resolve
|
||||||
|
console.log('\nTrying require.resolve:');
|
||||||
|
try {
|
||||||
|
const wasmPath = require.resolve('sql.js/dist/sql-wasm.wasm');
|
||||||
|
console.log('✅ Found via require.resolve:', wasmPath);
|
||||||
|
console.log(' Exists:', fs.existsSync(wasmPath) ? '✅' : '❌');
|
||||||
|
} catch (e) {
|
||||||
|
console.log('❌ Failed to resolve via require.resolve:', e.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find sql.js package location
|
||||||
|
console.log('\nTrying to find sql.js package:');
|
||||||
|
try {
|
||||||
|
const sqlJsPath = require.resolve('sql.js');
|
||||||
|
console.log('✅ Found sql.js at:', sqlJsPath);
|
||||||
|
const sqlJsDir = path.dirname(sqlJsPath);
|
||||||
|
const wasmFromSqlJs = path.join(sqlJsDir, '../dist/sql-wasm.wasm');
|
||||||
|
console.log(' Derived WASM path:', wasmFromSqlJs);
|
||||||
|
console.log(' Exists:', fs.existsSync(wasmFromSqlJs) ? '✅' : '❌');
|
||||||
|
} catch (e) {
|
||||||
|
console.log('❌ Failed to find sql.js package:', e.message);
|
||||||
|
}
|
||||||
@@ -117,14 +117,53 @@ async function createBetterSQLiteAdapter(dbPath: string): Promise<DatabaseAdapte
|
|||||||
* Create sql.js adapter with persistence
|
* Create sql.js adapter with persistence
|
||||||
*/
|
*/
|
||||||
async function createSQLJSAdapter(dbPath: string): Promise<DatabaseAdapter> {
|
async function createSQLJSAdapter(dbPath: string): Promise<DatabaseAdapter> {
|
||||||
const initSqlJs = require('sql.js');
|
let initSqlJs;
|
||||||
|
try {
|
||||||
|
initSqlJs = require('sql.js');
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('Failed to load sql.js module:', error);
|
||||||
|
throw new Error('sql.js module not found. This might be an issue with npm package installation.');
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize sql.js
|
// Initialize sql.js
|
||||||
const SQL = await initSqlJs({
|
const SQL = await initSqlJs({
|
||||||
// This will look for the wasm file in node_modules
|
// This will look for the wasm file in node_modules
|
||||||
locateFile: (file: string) => {
|
locateFile: (file: string) => {
|
||||||
if (file.endsWith('.wasm')) {
|
if (file.endsWith('.wasm')) {
|
||||||
return path.join(__dirname, '../../node_modules/sql.js/dist/', file);
|
// Try multiple paths to find the WASM file
|
||||||
|
const possiblePaths = [
|
||||||
|
// Local development path
|
||||||
|
path.join(__dirname, '../../node_modules/sql.js/dist/', file),
|
||||||
|
// When installed as npm package
|
||||||
|
path.join(__dirname, '../../../sql.js/dist/', file),
|
||||||
|
// Alternative npm package path
|
||||||
|
path.join(process.cwd(), 'node_modules/sql.js/dist/', file),
|
||||||
|
// Try to resolve from require
|
||||||
|
path.join(path.dirname(require.resolve('sql.js')), '../dist/', file)
|
||||||
|
];
|
||||||
|
|
||||||
|
// Find the first existing path
|
||||||
|
for (const tryPath of possiblePaths) {
|
||||||
|
if (fsSync.existsSync(tryPath)) {
|
||||||
|
if (process.env.MCP_MODE !== 'stdio') {
|
||||||
|
logger.debug(`Found WASM file at: ${tryPath}`);
|
||||||
|
}
|
||||||
|
return tryPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not found, try the last resort - require.resolve
|
||||||
|
try {
|
||||||
|
const wasmPath = require.resolve('sql.js/dist/sql-wasm.wasm');
|
||||||
|
if (process.env.MCP_MODE !== 'stdio') {
|
||||||
|
logger.debug(`Found WASM file via require.resolve: ${wasmPath}`);
|
||||||
|
}
|
||||||
|
return wasmPath;
|
||||||
|
} catch (e) {
|
||||||
|
// Fall back to the default path
|
||||||
|
logger.warn(`Could not find WASM file, using default path: ${file}`);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|||||||
13
test-claude-desktop-config.json
Normal file
13
test-claude-desktop-config.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"n8n-mcp-local": {
|
||||||
|
"command": "node",
|
||||||
|
"args": ["/Users/romualdczlonkowski/Pliki/n8n-mcp/n8n-mcp/dist/mcp/index.js"],
|
||||||
|
"env": {
|
||||||
|
"MCP_MODE": "stdio",
|
||||||
|
"LOG_LEVEL": "error",
|
||||||
|
"DISABLE_CONSOLE_OUTPUT": "true"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user