mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-03-31 14:43:09 +00:00
fix: raise session timeout default, fix VS Code MCP compatibility (#674)
* fix: raise session timeout default and fix VS Code MCP compatibility (#626, #600, #611) - #626: Raise SESSION_TIMEOUT_MINUTES default from 5 to 30 minutes. Complex editing sessions easily exceed 5 min between LLM calls. - #600: Add z.preprocess(tryParseJson, ...) to operations parameter in n8n_update_partial_workflow. VS Code extension sends arrays as JSON strings. - #611: Strip undefined values from tool args via JSON round-trip before Zod validation. VS Code sends explicit undefined which Zod's .optional() rejects. Conceived by Romuald Członkowski - https://www.aiadvisors.pl/en Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: deduplicate tryParseJson — export from handlers-n8n-manager tryParseJson was duplicated in handlers-workflow-diff.ts. Now imported from handlers-n8n-manager.ts where it was already defined. Updated test mock to use importOriginal so the real function is available. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
parent
fb2d306dc3
commit
6e4a9d520d
@@ -107,11 +107,10 @@ export class SingleSessionHTTPServer {
|
||||
private session: Session | null = null; // Keep for SSE compatibility
|
||||
private consoleManager = new ConsoleManager();
|
||||
private expressServer: any;
|
||||
// Session timeout reduced from 30 minutes to 5 minutes for faster cleanup
|
||||
// Configurable via SESSION_TIMEOUT_MINUTES environment variable
|
||||
// This prevents memory buildup from stale sessions
|
||||
// Session timeout — configurable via SESSION_TIMEOUT_MINUTES environment variable
|
||||
// Default 30 minutes: balances memory cleanup with real editing sessions (#626)
|
||||
private sessionTimeout = parseInt(
|
||||
process.env.SESSION_TIMEOUT_MINUTES || '5', 10
|
||||
process.env.SESSION_TIMEOUT_MINUTES || '30', 10
|
||||
) * 60 * 1000;
|
||||
private authToken: string | null = null;
|
||||
private cleanupTimer: NodeJS.Timeout | null = null;
|
||||
|
||||
@@ -2731,7 +2731,7 @@ const updateTableSchema = tableIdSchema.extend({
|
||||
|
||||
// MCP transports may serialize JSON objects/arrays as strings.
|
||||
// Parse them back, but return the original value on failure so Zod reports a proper type error.
|
||||
function tryParseJson(val: unknown): unknown {
|
||||
export function tryParseJson(val: unknown): unknown {
|
||||
if (typeof val !== 'string') return val;
|
||||
try { return JSON.parse(val); } catch { return val; }
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { z } from 'zod';
|
||||
import { McpToolResponse } from '../types/n8n-api';
|
||||
import { WorkflowDiffRequest, WorkflowDiffOperation, WorkflowDiffValidationError } from '../types/workflow-diff';
|
||||
import { WorkflowDiffEngine } from '../services/workflow-diff-engine';
|
||||
import { getN8nApiClient } from './handlers-n8n-manager';
|
||||
import { getN8nApiClient, tryParseJson } from './handlers-n8n-manager';
|
||||
import { N8nApiError, getUserFriendlyErrorMessage } from '../utils/n8n-errors';
|
||||
import { logger } from '../utils/logger';
|
||||
import { InstanceContext } from '../types/instance-context';
|
||||
@@ -39,7 +39,7 @@ const NODE_TARGETING_OPERATIONS = new Set([
|
||||
// Zod schema for the diff request
|
||||
const workflowDiffSchema = z.object({
|
||||
id: z.string(),
|
||||
operations: z.array(z.object({
|
||||
operations: z.preprocess(tryParseJson, z.array(z.object({
|
||||
type: z.string(),
|
||||
description: z.string().optional(),
|
||||
// Node operations
|
||||
@@ -87,7 +87,7 @@ const workflowDiffSchema = z.object({
|
||||
}
|
||||
}
|
||||
return op;
|
||||
})),
|
||||
}))),
|
||||
validateOnly: z.boolean().optional(),
|
||||
continueOnError: z.boolean().optional(),
|
||||
createBackup: z.boolean().optional(),
|
||||
|
||||
@@ -748,6 +748,13 @@ export class N8NDocumentationMCPServer {
|
||||
// tool's inputSchema as the source of truth.
|
||||
processedArgs = this.coerceStringifiedJsonParams(name, processedArgs);
|
||||
|
||||
// Strip undefined values from args (#611) — VS Code extension sends
|
||||
// explicit undefined values which Zod's .optional() rejects.
|
||||
// Removing them makes Zod treat them as missing (which .optional() allows).
|
||||
if (processedArgs) {
|
||||
processedArgs = JSON.parse(JSON.stringify(processedArgs));
|
||||
}
|
||||
|
||||
try {
|
||||
logger.debug(`Executing tool: ${name}`, { args: processedArgs });
|
||||
const startTime = Date.now();
|
||||
|
||||
Reference in New Issue
Block a user