mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-03-20 01:13:07 +00:00
Adds zero-configuration anonymous usage statistics to track: - Number of active users with deterministic user IDs - Which MCP tools AI agents use most - What workflows are built (sanitized to protect privacy) - Common errors and issues Key features: - Zero-configuration design with hardcoded write-only credentials - Privacy-first approach with comprehensive data sanitization - Opt-out support via config file and environment variables - Docker-friendly with environment variable support - Multi-process safe with immediate flush strategy - Row Level Security (RLS) policies for write-only access Technical implementation: - Supabase backend with anon key for INSERT-only operations - Workflow sanitization removes all sensitive data - Environment variables checked for opt-out (TELEMETRY_DISABLED, etc.) - Telemetry enabled by default but respects user preferences - Cleaned up all debug logging for production readiness 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
123 lines
4.0 KiB
JavaScript
123 lines
4.0 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
import { N8NDocumentationMCPServer } from './server';
|
|
import { logger } from '../utils/logger';
|
|
import { TelemetryConfigManager } from '../telemetry/config-manager';
|
|
|
|
// Add error details to stderr for Claude Desktop debugging
|
|
process.on('uncaughtException', (error) => {
|
|
if (process.env.MCP_MODE !== 'stdio') {
|
|
console.error('Uncaught Exception:', error);
|
|
}
|
|
logger.error('Uncaught Exception:', error);
|
|
process.exit(1);
|
|
});
|
|
|
|
process.on('unhandledRejection', (reason, promise) => {
|
|
if (process.env.MCP_MODE !== 'stdio') {
|
|
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
|
|
}
|
|
logger.error('Unhandled Rejection:', reason);
|
|
process.exit(1);
|
|
});
|
|
|
|
async function main() {
|
|
// Handle telemetry CLI commands
|
|
const args = process.argv.slice(2);
|
|
if (args.length > 0 && args[0] === 'telemetry') {
|
|
const telemetryConfig = TelemetryConfigManager.getInstance();
|
|
const action = args[1];
|
|
|
|
switch (action) {
|
|
case 'enable':
|
|
telemetryConfig.enable();
|
|
process.exit(0);
|
|
break;
|
|
case 'disable':
|
|
telemetryConfig.disable();
|
|
process.exit(0);
|
|
break;
|
|
case 'status':
|
|
console.log(telemetryConfig.getStatus());
|
|
process.exit(0);
|
|
break;
|
|
default:
|
|
console.log(`
|
|
Usage: n8n-mcp telemetry [command]
|
|
|
|
Commands:
|
|
enable Enable anonymous telemetry
|
|
disable Disable anonymous telemetry
|
|
status Show current telemetry status
|
|
|
|
Learn more: https://github.com/czlonkowski/n8n-mcp/blob/main/PRIVACY.md
|
|
`);
|
|
process.exit(args[1] ? 1 : 0);
|
|
}
|
|
}
|
|
|
|
const mode = process.env.MCP_MODE || 'stdio';
|
|
|
|
try {
|
|
// Only show debug messages in HTTP mode to avoid corrupting stdio communication
|
|
if (mode === 'http') {
|
|
console.error(`Starting n8n Documentation MCP Server in ${mode} mode...`);
|
|
console.error('Current directory:', process.cwd());
|
|
console.error('Node version:', process.version);
|
|
}
|
|
|
|
if (mode === 'http') {
|
|
// Check if we should use the fixed implementation
|
|
if (process.env.USE_FIXED_HTTP === 'true') {
|
|
// Use the fixed HTTP implementation that bypasses StreamableHTTPServerTransport issues
|
|
const { startFixedHTTPServer } = await import('../http-server');
|
|
await startFixedHTTPServer();
|
|
} else {
|
|
// HTTP mode - for remote deployment with single-session architecture
|
|
const { SingleSessionHTTPServer } = await import('../http-server-single-session');
|
|
const server = new SingleSessionHTTPServer();
|
|
|
|
// Graceful shutdown handlers
|
|
const shutdown = async () => {
|
|
await server.shutdown();
|
|
process.exit(0);
|
|
};
|
|
|
|
process.on('SIGTERM', shutdown);
|
|
process.on('SIGINT', shutdown);
|
|
|
|
await server.start();
|
|
}
|
|
} else {
|
|
// Stdio mode - for local Claude Desktop
|
|
const server = new N8NDocumentationMCPServer();
|
|
await server.run();
|
|
}
|
|
} catch (error) {
|
|
// In stdio mode, we cannot output to console at all
|
|
if (mode !== 'stdio') {
|
|
console.error('Failed to start MCP server:', error);
|
|
logger.error('Failed to start MCP server', error);
|
|
|
|
// Provide helpful error messages
|
|
if (error instanceof Error && error.message.includes('nodes.db not found')) {
|
|
console.error('\nTo fix this issue:');
|
|
console.error('1. cd to the n8n-mcp directory');
|
|
console.error('2. Run: npm run build');
|
|
console.error('3. Run: npm run rebuild');
|
|
} else if (error instanceof Error && error.message.includes('NODE_MODULE_VERSION')) {
|
|
console.error('\nTo fix this Node.js version mismatch:');
|
|
console.error('1. cd to the n8n-mcp directory');
|
|
console.error('2. Run: npm rebuild better-sqlite3');
|
|
console.error('3. If that doesn\'t work, try: rm -rf node_modules && npm install');
|
|
}
|
|
}
|
|
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// Run if called directly
|
|
if (require.main === module) {
|
|
main().catch(console.error);
|
|
} |