Implement n8n-MCP integration
This commit adds a complete integration between n8n workflow automation and the Model Context Protocol (MCP): Features: - MCP server that exposes n8n workflows as tools, resources, and prompts - Custom n8n node for connecting to MCP servers from workflows - Bidirectional bridge for data format conversion - Token-based authentication and credential management - Comprehensive error handling and logging - Full test coverage for core components Infrastructure: - TypeScript/Node.js project setup with proper build configuration - Docker support with multi-stage builds - Development and production docker-compose configurations - Installation script for n8n custom node deployment Documentation: - Detailed README with usage examples and API reference - Environment configuration templates - Troubleshooting guide 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
106
src/utils/logger.ts
Normal file
106
src/utils/logger.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
export enum LogLevel {
|
||||
ERROR = 0,
|
||||
WARN = 1,
|
||||
INFO = 2,
|
||||
DEBUG = 3,
|
||||
}
|
||||
|
||||
export interface LoggerConfig {
|
||||
level: LogLevel;
|
||||
prefix?: string;
|
||||
timestamp?: boolean;
|
||||
}
|
||||
|
||||
export class Logger {
|
||||
private config: LoggerConfig;
|
||||
private static instance: Logger;
|
||||
|
||||
constructor(config?: Partial<LoggerConfig>) {
|
||||
this.config = {
|
||||
level: LogLevel.INFO,
|
||||
prefix: 'n8n-mcp',
|
||||
timestamp: true,
|
||||
...config,
|
||||
};
|
||||
}
|
||||
|
||||
static getInstance(config?: Partial<LoggerConfig>): Logger {
|
||||
if (!Logger.instance) {
|
||||
Logger.instance = new Logger(config);
|
||||
}
|
||||
return Logger.instance;
|
||||
}
|
||||
|
||||
private formatMessage(level: string, message: string): string {
|
||||
const parts: string[] = [];
|
||||
|
||||
if (this.config.timestamp) {
|
||||
parts.push(`[${new Date().toISOString()}]`);
|
||||
}
|
||||
|
||||
if (this.config.prefix) {
|
||||
parts.push(`[${this.config.prefix}]`);
|
||||
}
|
||||
|
||||
parts.push(`[${level}]`);
|
||||
parts.push(message);
|
||||
|
||||
return parts.join(' ');
|
||||
}
|
||||
|
||||
private log(level: LogLevel, levelName: string, message: string, ...args: any[]): void {
|
||||
if (level <= this.config.level) {
|
||||
const formattedMessage = this.formatMessage(levelName, message);
|
||||
|
||||
switch (level) {
|
||||
case LogLevel.ERROR:
|
||||
console.error(formattedMessage, ...args);
|
||||
break;
|
||||
case LogLevel.WARN:
|
||||
console.warn(formattedMessage, ...args);
|
||||
break;
|
||||
default:
|
||||
console.log(formattedMessage, ...args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
error(message: string, ...args: any[]): void {
|
||||
this.log(LogLevel.ERROR, 'ERROR', message, ...args);
|
||||
}
|
||||
|
||||
warn(message: string, ...args: any[]): void {
|
||||
this.log(LogLevel.WARN, 'WARN', message, ...args);
|
||||
}
|
||||
|
||||
info(message: string, ...args: any[]): void {
|
||||
this.log(LogLevel.INFO, 'INFO', message, ...args);
|
||||
}
|
||||
|
||||
debug(message: string, ...args: any[]): void {
|
||||
this.log(LogLevel.DEBUG, 'DEBUG', message, ...args);
|
||||
}
|
||||
|
||||
setLevel(level: LogLevel): void {
|
||||
this.config.level = level;
|
||||
}
|
||||
|
||||
static parseLogLevel(level: string): LogLevel {
|
||||
switch (level.toLowerCase()) {
|
||||
case 'error':
|
||||
return LogLevel.ERROR;
|
||||
case 'warn':
|
||||
return LogLevel.WARN;
|
||||
case 'debug':
|
||||
return LogLevel.DEBUG;
|
||||
case 'info':
|
||||
default:
|
||||
return LogLevel.INFO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a default logger instance
|
||||
export const logger = Logger.getInstance({
|
||||
level: Logger.parseLogLevel(process.env.LOG_LEVEL || 'info'),
|
||||
});
|
||||
Reference in New Issue
Block a user