Skip to main content
← All rules

mcp-scan rule

Node inline execution

node-inline-executionhigh

What mcp-scan saw

The AST scanner matched the word node as its own token in the joined command, followed later by -e as a standalone flag (a space or end-of-string after it). The check was deliberately narrowed so that --eval and flags merely containing -e, such as --experimental-modules, do not match.

Why it fires

Inline code never reaches a file, so nothing in your workflow reviews it: no diff, no linter, no code-signing, and no integrity check on the next run. It also makes the config the source of truth for behaviour, which means anyone who can edit the config can change what the server does without touching any repository.

When this is a false positive

  • \bnode\b matches inside hyphenated names because a hyphen is a word boundary. A package named mcp-node-tools or server-node invoked with an unrelated -e flag satisfies both halves.
  • A wrapper that passes -e through to a different program, for example a runner that takes -e for environment selection, matches whenever node appears anywhere in the same command line.
  • A short inline shim used to set NODE_OPTIONS or register a loader before the real entry point. It is auditable and stable, but it looks identical to an inline payload.

How to fix it

  1. Read the joined command in the finding and find the actual -e payload.
  2. Move the payload into a .js file next to your config and point the args at the file path.
  3. If the shim only sets an option, use NODE_OPTIONS in the server's env block instead of an inline script.
  4. If -e belongs to a different program in the same command line, reorder the arguments so it does not follow a node token, or rename the flag.
  5. Re-scan. The rule needs both a node token and a standalone -e, so either change clears it.