Local Tools

Local tools run directly inside the Contenox process — no network, no subprocess, no protocol overhead. They are the fastest way to give a model access to the machine it's running on.

local_fs — Filesystem access

Always available. Provides read, write, search, and metadata operations scoped to a configured directory. All paths are validated against the allowed directory; attempts to escape with ../ are rejected.

Configure the allowed root via contenox config set local-exec-allowed-dir /path/to/project or the --allowed-dir flag.

Tools

ToolParametersDescription
read_filepathRead the full content of a file
write_filepath, contentWrite content to a file (creates parent dirs, overwrites)
list_dirpath (optional)List entries in a directory (dirs marked with /)
read_file_rangepath, start_line, end_lineRead a specific line range
greppath, patternFind lines containing a string (returns line_number: content)
sedpath, pattern, replacementReplace all occurrences of a string in a file
count_statspathCount lines, words, and bytes (like wc)
stat_filepathGet file metadata: name, size, mod time, isDir

Chain example

"execute_config": {
  "model": "qwen2.5:7b",
  "provider": "ollama",
  "tools": ["local_fs"]
}

webhook — Arbitrary HTTP calls

Always available. Lets the model call any HTTP endpoint directly. Unlike remote tools (which require an OpenAPI spec), webhook is a single generic tool — the model decides the URL, method, query params, and headers at call time.

Caution

Because the model controls the destination URL, only use the webhook tools in chains where the model prompt restricts the scope (e.g. "only call endpoints on api.internal"). Do not use it in chains exposed to untrusted user input.

Tool

webhook

ParameterTypeRequiredDescription
urlstringThe URL to call
methodstringHTTP method: GET, POST, PUT, PATCH, DELETE (default: POST)
querystringQuery string (e.g. q=foo&limit=10)
headersobjectJSON object of headers to add

Chain example

"execute_config": {
  "model": "qwen2.5:7b",
  "provider": "ollama",
  "tools": ["webhook"]
}

local_shell — Shell command execution

Caution

local_shell gives the model direct access to run arbitrary commands on your machine. Never enable it in public-facing deployments or when processing untrusted user input.

Opt-in only — disabled by default. Enable per-invocation with the --shell flag:

contenox run --shell "clean up unused imports in the codebase"
contenox plan next --auto --shell

Command policy is set in the chain, not on the CLI. Add a tools_policies block to execute_config:

"execute_config": {
  "model": "{{var:model}}",
  "provider": "{{var:provider}}",
  "tools": ["local_shell"],
  "tools_policies": {
    "local_shell": {
      "_allowed_commands": "git,go,make,ls,cat",
      "_denied_commands":  "sudo,su,dd,mkfs"
    }
  }
}
  • _allowed_commands — comma-separated list of permitted command names. When set, any command not on this list is rejected before it runs.
  • _denied_commands — comma-separated commands that are always blocked, regardless of the allowlist.
  • _allowed_dir — if set, the command (or its absolute path) must reside under this directory.

The default chains (default-chain.json, default-run-chain.json) ship with sensible defaults: common dev tools allowed, privilege-escalation and raw-disk commands denied.

To use local_shell with no policy restrictions (fully open), omit tools_policies entirely. Only do this in fully-trusted, local-only environments. Review tool use in your chain and use --shell only when you intend to grant shell access.

Tool

local_shell

ParameterTypeRequiredDescription
commandstringExecutable path or name
argsstringSpace-separated arguments
cwdstringWorking directory
timeoutstringDuration e.g. 30s
shellbooleanRun via /bin/sh -c (allows pipes, redirects, $VAR). Disabled when _allowed_commands or _allowed_dir is set.


ssh — Remote command execution

Always available. Runs a single command on a remote host over SSH. Supports password and private-key authentication.

Caution

The model controls the command string and target host. Restrict ssh to chains with tightly scoped system instructions and trusted user input only.

Tool

execute_remote_command

ParameterTypeRequiredDescription
hoststringRemote hostname or IP
userstringSSH username
commandstringCommand to execute
portintSSH port (default: 22)
passwordstringPassword authentication
private_keystringPEM-encoded private key content
private_key_filestringPath to a private key file
timeoutstringDuration, e.g. "30s" (default: "30s")
host_keystringExpected host key fingerprint (SHA-256)
strict_host_keyboolEnforce host key verification (default: true)

Returns a JSON object with fields: exit_code, stdout, stderr, duration_seconds, command, host, success.

Use output_template on the task to extract specific fields:

"output_template": "Exit <span v-pre>{{.exit_code}}</span>: <span v-pre>{{.stdout}}</span>"

Chain example

"execute_config": {
  "model": "qwen2.5:7b",
  "provider": "ollama",
  "tools": ["ssh"]
}

plan_manager — Multi-step plan orchestration

Always available. Exposes plan lifecycle tools so the model can create, drive, and inspect a structured execution plan stored in the local database.

Tools

ToolParametersDescription
create_plangoal: stringGenerate a step-by-step plan; returns {plan_name, goal, steps}
run_next_stepExecute the next pending step; returns {ordinal, description, status, result}
get_plan_statusReturns {plan_name, goal, status, steps[]} with per-step status and result
retry_stepordinal: intReset a failed or skipped step to pending
skip_stepordinal: intMark a step as skipped

Pair plan_manager with plan_summary in the same chain to persist step results. See Example 5 for a complete chain.

Chain example

"execute_config": {
  "model": "qwen2.5:7b",
  "provider": "ollama",
  "tools": ["plan_manager", "local_shell", "local_fs"]
}

plan_summary — Persist plan results

Always available. Used in the summariser task of a planning chain. Writes the summariser's output to the local plan database. plan_summary reads the active plan and step ID from the chain context — it must run within a chain driven by plan_manager.

Tools

ToolDescription
persistValidates the summariser JSON output and writes it to the database; returns "ok" or "invalid"
fallbackUnconditional write on summariser failure; always returns "done"

Chain example

"execute_config": {
  "model": "qwen2.5:7b",
  "provider": "ollama",
  "tools": ["plan_summary"]
}

Always available. Appends a message to the chat history as a system message, or returns the message as a plain string when no chat history is active.

Tool

print

ParameterTypeRequiredDescription
messagestringText to append or return

Chain example

"execute_config": {
  "model": "qwen2.5:7b",
  "provider": "ollama",
  "tools": ["print"]
}

echo — Debug passthrough

Always available. Echoes the input back, prefixed with "Echo: ". Useful for verifying what a task receives during chain development.

Tool

echo

ParameterTypeRequiredDescription
inputstringText to echo

Chain example

"execute_config": {
  "model": "qwen2.5:7b",
  "provider": "ollama",
  "tools": ["echo"]
}

Adding custom local tools

Adding new local tools types requires modifying the Contenox Go source code and implementing the taskengine.HookRepo interface. For custom capabilities without writing Go, build a small HTTP service (FastAPI, Express, etc.) and register it as a Remote Tools instead — no code changes required.