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
| Tool | Parameters | Description |
|---|---|---|
read_file | path | Read the full content of a file |
write_file | path, content | Write content to a file (creates parent dirs, overwrites) |
list_dir | path (optional) | List entries in a directory (dirs marked with /) |
read_file_range | path, start_line, end_line | Read a specific line range |
grep | path, pattern | Find lines containing a string (returns line_number: content) |
sed | path, pattern, replacement | Replace all occurrences of a string in a file |
count_stats | path | Count lines, words, and bytes (like wc) |
stat_file | path | Get 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
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | ✅ | The URL to call |
method | string | — | HTTP method: GET, POST, PUT, PATCH, DELETE (default: POST) |
query | string | — | Query string (e.g. q=foo&limit=10) |
headers | object | — | JSON 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
| Parameter | Type | Required | Description |
|---|---|---|---|
command | string | ✅ | Executable path or name |
args | string | — | Space-separated arguments |
cwd | string | — | Working directory |
timeout | string | — | Duration e.g. 30s |
shell | boolean | — | Run 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
| Parameter | Type | Required | Description |
|---|---|---|---|
host | string | ✅ | Remote hostname or IP |
user | string | ✅ | SSH username |
command | string | ✅ | Command to execute |
port | int | — | SSH port (default: 22) |
password | string | — | Password authentication |
private_key | string | — | PEM-encoded private key content |
private_key_file | string | — | Path to a private key file |
timeout | string | — | Duration, e.g. "30s" (default: "30s") |
host_key | string | — | Expected host key fingerprint (SHA-256) |
strict_host_key | bool | — | Enforce 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
| Tool | Parameters | Description |
|---|---|---|
create_plan | goal: string | Generate a step-by-step plan; returns {plan_name, goal, steps} |
run_next_step | — | Execute the next pending step; returns {ordinal, description, status, result} |
get_plan_status | — | Returns {plan_name, goal, status, steps[]} with per-step status and result |
retry_step | ordinal: int | Reset a failed or skipped step to pending |
skip_step | ordinal: int | Mark 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
| Tool | Description |
|---|---|
persist | Validates the summariser JSON output and writes it to the database; returns "ok" or "invalid" |
fallback | Unconditional write on summariser failure; always returns "done" |
Chain example
"execute_config": {
"model": "qwen2.5:7b",
"provider": "ollama",
"tools": ["plan_summary"]
}
print — Append to conversation
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
| Parameter | Type | Required | Description |
|---|---|---|---|
message | string | ✅ | Text 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
| Parameter | Type | Required | Description |
|---|---|---|---|
input | string | ✅ | Text 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.