FlowiseAI/Flowise · error · Error

Custom MCP script path not in allowed list.

Error message

Custom MCP script path not in allowed list.

What it means

Thrown by validateArgsForLocalFileAccess when CUSTOM_MCP_ALLOWED_ABSOLUTE_SCRIPT_PATHS is non-empty but the first argument (args[0], treated as the script path) is not present in the allow-list. The check is a strict equality membership test, so path normalization mismatches fail it.

Source

Thrown at packages/components/nodes/tools/MCP/core.ts:259

            name: name,
            description: description,
            schema: argsSchema
        }
    )
}

export const validateArgsForLocalFileAccess = (args: string[]): void => {
    const allowedScriptPaths = (process.env.CUSTOM_MCP_ALLOWED_ABSOLUTE_SCRIPT_PATHS ?? '')
        .split(',')
        .map((s) => s.trim())
        .filter(Boolean)

    const scriptArg = args[0]

    if (allowedScriptPaths.length === 0)
        throw new Error('Custom MCP script execution disabled. Configure CUSTOM_MCP_ALLOWED_ABSOLUTE_SCRIPT_PATHS environment variable.')

    if (!allowedScriptPaths.includes(scriptArg)) throw new Error('Custom MCP script path not in allowed list.')
}

export const validateCommandInjection = (args: string[]): void => {
    const dangerousPatterns = [
        // Shell metacharacters
        /[;&|`$(){}[\]<>]/,
        // Command chaining
        /&&|\|\||;;/,
        // Redirections
        />>|<<|>/,
        // Backticks and command substitution
        /`|\$\(/,
        // Process substitution
        /<\(|>\(/
    ]

    for (const arg of args) {
        if (typeof arg !== 'string') continue

View on GitHub (pinned to abe4a8601a)

Solutions

  1. Make args[0] an absolute path identical to an allow-list entry (same resolution, no trailing slash).
  2. Add the exact path being passed (print it once to compare) to CUSTOM_MCP_ALLOWED_ABSOLUTE_SCRIPT_PATHS.
  3. Resolve symlinks/relative segments on both sides so the strings match byte-for-byte.

Example fix

// before: args[0] = './server.js', allow-list = /opt/mcp/server.js

// after: pass the same absolute path
const scriptPath = path.resolve('/opt/mcp/server.js')
const serverParams = { command: 'node', args: [scriptPath] }
Defensive patterns

Strategy: validation

Validate before calling

const allowed = (process.env.CUSTOM_MCP_ALLOWED_ABSOLUTE_SCRIPT_PATHS ?? '').split(',').map(s => s.trim()).filter(Boolean)
const scriptArg = path.resolve(args[0])
if (!allowed.includes(scriptArg)) {
  throw new Error(`Script path ${scriptArg} not in allow-list. Add it to CUSTOM_MCP_ALLOWED_ABSOLUTE_SCRIPT_PATHS`)
}

Type guard

const scriptPathAllowed = (scriptPath: string): boolean => {
  const allowed = (process.env.CUSTOM_MCP_ALLOWED_ABSOLUTE_SCRIPT_PATHS ?? '').split(',').map(s => s.trim()).filter(Boolean)
  return allowed.includes(path.resolve(scriptPath))
}

Try / catch

try {
  validateArgsForLocalFileAccess(args)
} catch (e) {
  if (e.message === 'Custom MCP script path not in allowed list.') {
    // resolve args[0] to absolute and compare to allow-list entries
  }
  throw e
}

Prevention

When it happens

Trigger: args[0] is a path that differs from every entry in the allow-list: relative vs absolute, symlink, trailing slash, case difference on case-sensitive filesystems, or simply a different file.

Common situations: Operator allow-listed /opt/mcp/server.js but node passes ./server.js or /opt/mcp/server.js/; package path resolved differently across deploys; copy-paste typo in the env var.

Related errors


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