FlowiseAI/Flowise · error · Error

cwd parameter is not allowed in MCP server configuration

Error message

cwd parameter is not allowed in MCP server configuration

What it means

Thrown by validateMCPServerConfig when serverParams.cwd != null. The cwd field would let a caller set the working directory of the spawned MCP process, which is treated as an escalation risk (relative-path hijacking, accessing sensitive dirs), so it is unconditionally rejected.

Source

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

}

/**
 * Validates a user-supplied MCP server configuration against operator-controlled allow-lists.
 *
 * For stdio configs, the command must appear in the `CUSTOM_MCP_ALLOWED_COMMANDS` allow-list
 * (comma-separated, empty = none allowed). The list is empty by default, so no command can run
 * until an operator explicitly opts in. To enable local/custom stdio MCP servers, set
 * `CUSTOM_MCP_PROTOCOL=stdio` and `CUSTOM_MCP_ALLOWED_COMMANDS` in your env file
 * (see docker/.env.example, docker/worker/.env.example, packages/server/.env.example).
 */
export const validateMCPServerConfig = (serverParams: any): void => {
    // Validate the entire server configuration
    if (!serverParams || typeof serverParams !== 'object') {
        throw new Error('Invalid server configuration')
    }

    if (serverParams.cwd != null) {
        throw new Error('cwd parameter is not allowed in MCP server configuration')
    }

    // Command allowlist - operator-controlled via CUSTOM_MCP_ALLOWED_COMMANDS (empty = none allowed)
    const allowedCommands = (process.env.CUSTOM_MCP_ALLOWED_COMMANDS ?? '')
        .split(',')
        .map((s) => s.trim())
        .filter(Boolean)

    if (serverParams.command && !allowedCommands.includes(serverParams.command)) {
        throw new Error(`Command '${serverParams.command}' is not allowed. Permitted: ${allowedCommands.join(', ') || '(none)'}`)
    }

    // Validate arguments if present
    if (serverParams.args && Array.isArray(serverParams.args)) {
        validateArgsForLocalFileAccess(serverParams.args)
        validateCommandInjection(serverParams.args)

        // Validate command-specific dangerous flags

View on GitHub (pinned to abe4a8601a)

Solutions

  1. Remove the cwd key from serverParams before validation.
  2. Set the working directory at the OS/process level for the worker instead of per-MCP-server.
  3. If a specific working directory is required, wrap the command in a small launcher script and allow-list that script path.

Example fix

// before
const serverParams = { command: 'node', args: ['s.js'], cwd: '/opt/app' }

// after
const serverParams = { command: 'node', args: ['/opt/app/s.js'] } // absolute path, no cwd
Defensive patterns

Strategy: validation

Validate before calling

if (serverParams && Object.prototype.hasOwnProperty.call(serverParams, 'cwd')) {
  delete serverParams.cwd // or throw to forbid explicitly
}

Type guard

const hasNoCwd = (p: any): boolean => p == null || typeof p !== 'object' || !('cwd' in p)

Try / catch

try {
  validateMCPServerConfig(serverParams)
} catch (e) {
  if (e.message === 'cwd parameter is not allowed in MCP server configuration') {
    // remove cwd from serverParams and retry
  }
  throw e
}

Prevention

When it happens

Trigger: A caller constructs serverParams with a cwd key, e.g. { command: 'node', args: [...], cwd: '/opt/app' }. StdioClientTransport would otherwise honor cwd, so the validator forbids it.

Common situations: Caller copies a full StdioServerParameters object including cwd; framework defaults cwd to process.cwd() and forwards it; operator tries to sandbox the MCP server to a directory.

Related errors


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