Shell Tool¶
The Shell tool executes commands and multi-line scripts on the host system with layered safety controls: command allowlisting, dangerous pattern blocking, working directory restrictions, timeouts, and output truncation.
Quick Reference¶
| Property | Value |
|---|---|
| Node name | tools/shell |
| Version | 0.1.0 |
| Library | execa |
| Actions | execute, script |
| Tags | shell, bash, terminal, command, tools, agentic |
Actions¶
execute¶
Run a single command with optional arguments.
| Parameter | Type | Required | Description |
|---|---|---|---|
command |
string | Yes | The command to execute |
args |
string[] | No | Arguments to pass to the command |
cwd |
string | No | Working directory |
env |
Record\<string, string> | No | Additional environment variables |
timeout |
integer | No | Timeout in milliseconds (capped by maxTimeout) |
stdin |
string | No | Data to pipe to stdin |
script¶
Execute a multi-line script by writing it to a temporary file and running it through the specified shell.
| Parameter | Type | Required | Description |
|---|---|---|---|
script |
string | Yes | Multi-line script content |
shell |
string | No | Shell interpreter (default: bash). Also supports sh, zsh. |
cwd |
string | No | Working directory |
env |
Record\<string, string> | No | Additional environment variables |
timeout |
integer | No | Timeout in milliseconds (capped by maxTimeout) |
stdin |
string | No | Data to pipe to stdin |
Note
The temporary script file is created with mode 0o700 and is always cleaned up after execution, even on error.
Output Schema¶
| Field | Type | Description |
|---|---|---|
stdout |
string | Standard output (may be truncated) |
stderr |
string | Standard error (may be truncated) |
exitCode |
number | Process exit code |
duration |
number | Execution time in milliseconds |
success |
boolean | true if exit code is 0 |
Configuration Reference¶
| Property | Type | Default | Description |
|---|---|---|---|
allowedCommands |
string[] | (none) | If set, only these base command names are allowed. |
blockedPatterns |
string[] | See below | Regex patterns that are always blocked. |
maxTimeout |
integer | 30000 (30s) |
Maximum execution time in milliseconds. |
allowedCwd |
string[] | (none) | If set, only these working directories are allowed. |
maxOutputSize |
integer | 1000000 (1MB) |
Truncate stdout/stderr beyond this byte count. |
Default Blocked Patterns¶
The following 7 regex patterns are blocked by default:
| Pattern | What it blocks |
|---|---|
rm\s+-rf\s+/ |
Recursive deletion from root |
mkfs |
Filesystem formatting |
:()\{ |
Fork bomb patterns |
dd\s+if= |
Raw disk writes with dd |
> /dev/sd |
Direct writes to block devices |
chmod\s+777 |
World-writable permissions |
curl.*\|.*sh |
Pipe-to-shell execution |
You can override or extend this list via the blockedPatterns config property.
Safety¶
Command allowlisting¶
When allowedCommands is configured, the tool extracts the base command name (stripping any path prefix) and checks it against the list. For example, if allowedCommands is ["node", "npm", "git"], then /usr/bin/node is allowed (base name node matches) but python is rejected.
Regex blocklist¶
Every command string (including the full command + args for execute, and every line for script) is tested against all blockedPatterns. A match on any pattern rejects the command immediately.
Working directory restrictions¶
When allowedCwd is set, the cwd parameter is resolved to an absolute path and must fall within one of the allowed directories. This prevents execution in sensitive directories.
Timeout enforcement¶
The effective timeout is Math.min(input.timeout, config.maxTimeout). If a process exceeds the timeout, it is terminated.
Output truncation¶
Both stdout and stderr are truncated to maxOutputSize bytes. Truncated output receives a "... [output truncated]" suffix.
Warning
If allowedCommands is not set, any command is allowed (subject to the blocklist). Always configure allowedCommands in production environments.
Usage Example¶
import { shellNode } from '@flowforgejs/nodes';
const workflow = {
nodes: [
{
id: 'run-build',
node: shellNode,
config: {
allowedCommands: ['npm', 'node', 'tsc'],
maxTimeout: 60_000,
allowedCwd: ['/app/project'],
},
input: {
action: 'execute',
command: 'npm',
args: ['run', 'build'],
cwd: '/app/project',
},
},
],
};
Tip
Use the script action for multi-step operations that need to share shell state (variables, conditionals). The execute action is better for single commands where you want structured argument passing.