FlowiseAI/Flowise · error · Error

Invalid MCP Server Config: ${error}

Error message

Invalid MCP Server Config: ${error}

What it means

Thrown by the outer catch in CustomMCP.getTools for ANY error during server-param substitution, security validation, MCPToolkit construction, or toolkit.initialize() that wasn't already re-thrown as a more specific error (392, 393). It is a catch-all wrapper that prefixes the underlying error. Common underlying causes: JSON.parse failure on the substituted config string (convertToValidJSONString couldn't repair it), toolkit.initialize() network/DNS failure, or a security-check re-throw nesting.

Source

Thrown at packages/components/nodes/tools/MCP/CustomMCP/CustomMCP.ts:199

                }
            }

            // Compatible with stdio and SSE
            let toolkit: MCPToolkit
            if (process.env.CUSTOM_MCP_PROTOCOL === 'stdio' && serverParams!.command) toolkit = new MCPToolkit(serverParams, 'stdio')
            else toolkit = new MCPToolkit(serverParams, 'sse')

            await toolkit.initialize()

            const tools = toolkit.tools ?? []

            if (options.cachePool) {
                await options.cachePool.addMCPCache(cacheKey, { toolkit, tools })
            }

            return tools as Tool[]
        } catch (error) {
            throw new Error(`Invalid MCP Server Config: ${error}`)
        }
    }
}

function substituteVariablesInObject(obj: any, sandbox: any): any {
    if (typeof obj === 'string') {
        // Replace variables in string values
        return substituteVariablesInString(obj, sandbox)
    } else if (Array.isArray(obj)) {
        // Recursively process arrays
        return obj.map((item) => substituteVariablesInObject(item, sandbox))
    } else if (obj !== null && typeof obj === 'object') {
        // Recursively process object properties
        const result: any = {}
        for (const [key, value] of Object.entries(obj)) {
            result[key] = substituteVariablesInObject(value, sandbox)
        }
        return result

View on GitHub (pinned to abe4a8601a)

Solutions

  1. Read the inner error string after 'Invalid MCP Server Config:' — it is the real cause (parse position, connect ECONNREFUSED, spawn ENOENT, etc.).
  2. If the inner error is 'Security validation failed', apply the 393 fix.
  3. If JSON parse, validate the substituted config string with JSON.parse in isolation and fix the variable value.
  4. If connect/spawn, verify the URL is reachable / the command binary exists before the tool call.
  5. Test the config in a plain MCPToolkit.initialize() call outside Flowise to isolate.

Example fix

// before — variable injection broke JSON
mcpServerConfig: '{"url":"{{$vars.endpoint}}"}' with $vars.endpoint = 'https://x".com'
// after — sanitize variable values
$vars.endpoint = 'https://x.com'
Defensive patterns

Strategy: try-catch

Validate before calling

function preflightMcpConfig(raw: string, sandbox: any) {
  const subbed = substituteVariablesInString(raw, sandbox)
  const repaired = convertToValidJSONString(subbed)
  let obj: any
  try { obj = JSON.parse(repaired) } catch (e) { throw new Error(`config won't parse: ${(e as Error).message}`) }
  if (process.env.CUSTOM_MCP_SECURITY_CHECK !== 'false') validateMCPServerConfig(obj)
  return obj
}

Try / catch

try {
  return await customMcp.getTools(nodeData, options)
} catch (e) {
  // strip the wrapper to get the inner cause
  const inner = e instanceof Error ? e.message.replace(/^Invalid MCP Server Config: /, '') : String(e)
  if (/Security validation/.test(inner)) return fixConfigAndRetry()
  if (/ECONNREFUSED|ENOTFOUND|spawn ENOENT/.test(inner)) return reportUnreachable(inner)
  throw e
}

Prevention

When it happens

Trigger: The substituted mcpServerConfig is not valid JSON (e.g. unbalanced braces after variable injection); the MCPToolkit fails to connect to the SSE url (DNS, TLS, 401); a stdio command's binary is not found; or error 393 propagates through this catch (producing a doubly-wrapped message). The wrapper obscures the root cause, so the inner message must be read.

Common situations: Variable substitution injecting a value with unescaped quotes breaking JSON; MCP server URL wrong/offline; stdio command not on PATH; env vars missing for the stdio process; cascading from a security-validation failure.

Related errors


AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12). Data as JSON: /api/errors/d559c96cee222db7. Report an issue: GitHub.