mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-02-06 05:23:08 +00:00
- Add ConsoleManager to prevent console output interference with StreamableHTTPServerTransport - Implement SingleSessionHTTPServer with persistent session reuse - Create N8NMCPEngine for clean service integration - Add automatic session expiry after 30 minutes of inactivity - Update logger to be HTTP-aware during active requests - Maintain backward compatibility with existing deployments This fixes the "stream is not readable" error by implementing the Hybrid Single-Session architecture as documented in MCP_ERROR_FIX_PLAN.md 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
83 lines
2.0 KiB
TypeScript
83 lines
2.0 KiB
TypeScript
/**
|
|
* Console Manager for MCP HTTP Server
|
|
*
|
|
* Prevents console output from interfering with StreamableHTTPServerTransport
|
|
* by silencing console methods during MCP request handling.
|
|
*/
|
|
export class ConsoleManager {
|
|
private originalConsole = {
|
|
log: console.log,
|
|
error: console.error,
|
|
warn: console.warn,
|
|
info: console.info,
|
|
debug: console.debug,
|
|
trace: console.trace
|
|
};
|
|
|
|
private isSilenced = false;
|
|
|
|
/**
|
|
* Silence all console output
|
|
*/
|
|
public silence(): void {
|
|
if (this.isSilenced || process.env.MCP_MODE !== 'http') {
|
|
return;
|
|
}
|
|
|
|
this.isSilenced = true;
|
|
process.env.MCP_REQUEST_ACTIVE = 'true';
|
|
console.log = () => {};
|
|
console.error = () => {};
|
|
console.warn = () => {};
|
|
console.info = () => {};
|
|
console.debug = () => {};
|
|
console.trace = () => {};
|
|
}
|
|
|
|
/**
|
|
* Restore original console methods
|
|
*/
|
|
public restore(): void {
|
|
if (!this.isSilenced) {
|
|
return;
|
|
}
|
|
|
|
this.isSilenced = false;
|
|
process.env.MCP_REQUEST_ACTIVE = 'false';
|
|
console.log = this.originalConsole.log;
|
|
console.error = this.originalConsole.error;
|
|
console.warn = this.originalConsole.warn;
|
|
console.info = this.originalConsole.info;
|
|
console.debug = this.originalConsole.debug;
|
|
console.trace = this.originalConsole.trace;
|
|
}
|
|
|
|
/**
|
|
* Wrap an operation with console silencing
|
|
* Automatically restores console on completion or error
|
|
*/
|
|
public async wrapOperation<T>(operation: () => T | Promise<T>): Promise<T> {
|
|
this.silence();
|
|
try {
|
|
const result = operation();
|
|
if (result instanceof Promise) {
|
|
return await result.finally(() => this.restore());
|
|
}
|
|
this.restore();
|
|
return result;
|
|
} catch (error) {
|
|
this.restore();
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if console is currently silenced
|
|
*/
|
|
public get isActive(): boolean {
|
|
return this.isSilenced;
|
|
}
|
|
}
|
|
|
|
// Export singleton instance for easy use
|
|
export const consoleManager = new ConsoleManager(); |