bytedance/deer-flow · error · HTTPException
MCP server '{name}' passes '{exec_flag}' to '{command_name}'
Error message
MCP server '{name}' passes '{exec_flag}' to '{command_name}', which would run arbitrary code. Point the server at a package or module instead. What it means
400 raised when the args passed to an allowlisted launcher contain a flag that turns it into an arbitrary code executor — e.g. node/python -e, npx -c, or uv's --with/extras forms evaluated unsafely. The screening function _arbitrary_exec_arg detects these flags so an API caller cannot use an approved binary as a general code runner.
Source
Thrown at backend/app/gateway/routers/mcp.py:615
allowlisted binary into an arbitrary code evaluator.
"""
allowed_commands = _allowed_stdio_commands()
for name, server in request.mcp_servers.items():
transport_type = (server.type or "stdio").lower()
if transport_type != "stdio":
continue
command_name = _stdio_command_name(server.command, server_name=name)
if command_name not in allowed_commands:
allowed = ", ".join(sorted(allowed_commands)) or "<none>"
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=(f"MCP server '{name}' uses disallowed stdio command '{command_name}'. Allowed commands: {allowed}. Configure {_MCP_STDIO_COMMAND_ALLOWLIST_ENV} to extend this list."),
)
exec_flag = _arbitrary_exec_arg(server.args, command=command_name)
if exec_flag is not None:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=(f"MCP server '{name}' passes '{exec_flag}' to '{command_name}', which would run arbitrary code. Point the server at a package or module instead."),
)
for env_name in server.env:
if env_name.strip().upper() in _CODE_INJECTING_ENV_VARS:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=(f"MCP server '{name}' sets environment variable '{env_name}', which would run arbitrary code at process startup."),
)
def _mask_server_config(server: McpServerConfigResponse) -> McpServerConfigResponse:
"""Return a copy of server config with sensitive fields masked.
Masks env values, header values, and removes OAuth secrets so they
are not exposed through the GET API endpoint.
"""View on GitHub (pinned to 1dd6ba1acb)
Solutions
- Package the code as a module/package and point the launcher at it (e.g. uvx --from ./pkg server, npx -y package)
- Remove -e/-c style flags from args entirely
- Run genuinely custom code as a local MCP server via a non-API mechanism (operator-managed config) rather than through the API boundary
Example fix
# before
{"command": "node", "args": ["-e", "require('my-server').start()"]}
# after
{"command": "npx", "args": ["-y", "my-mcp-server"]} Defensive patterns
Strategy: validation
Validate before calling
const EXEC_FLAGS = new Set(['-e', '--eval', '-c', '--command']);
function assertNoExecFlags(args: string[]) { for (const a of args) if (EXEC_FLAGS.has(a)) throw new Error(`arg ${a} turns the launcher into an arbitrary code runner; use a package/module instead`); } Type guard
null
Try / catch
null
Prevention
- Package inline scripts as a real module before exposing them as MCP servers
- Never transliterate docker run one-liners into MCP args
- Run custom code as an operator-managed (file-based) server, not via the API
When it happens
Trigger: Submitting args like ['-c', 'import os; ...'] to python, ['-e', 'script'] to node, or any eval-style flag detected for the chosen command; adapting a CLI recipe that uses -e into the MCP args array.
Common situations: Trying to shim a server with an inline script instead of packaging it; porting docker-style one-liners into MCP args; misunderstanding that the allowlist approves the binary, not arbitrary invocations of it.
Related errors
- MCP server '{server_name}' command must be a single executab
- MCP server '{name}' uses disallowed stdio command '{command_
- MCP server '{name}' sets environment variable '{env_name}',
- MCP server '{server_name}' with stdio transport requires a c
- Cannot set extra config key '{key}' to masked value '***'; p
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/adc06a612f0e64f9.
Report an issue: GitHub.