Skip to Content
GuidesTools

Tools

Tools are how the model acts on your machine. FreeCode ships 19 built-ins — file I/O, search, code intelligence, shell, web access, sub-agents, memory — plus whatever an MCP server exposes. Concurrency-safe tools are batched and run in parallel; mutating tools run one at a time, in order.

Long-running commands

A bash call holds the model’s turn until the command finishes, so anything long — a full test or eval suite, a build, a dev server — has to leave the foreground. Three mechanisms make sure it does, and that the result still comes back.

Background shells. bash with run_in_background: true returns a shell id (bash_1) at once and the process keeps running. Watch it with /shells; the model reads new output with bashoutput and stops it with killbash.

You are told when it exits. When a background command exits, the agent gets a <task-notification> with the exit code and the last 4,000 characters of output, and you see Background command completed: <command>. If the agent is mid-turn it arrives between tool calls; if the session is idle, FreeCode starts a turn so the agent reports back without you asking. So “run the eval suite and tell me the result” works even when the suite takes hours. No notification is sent when the agent already knows the outcome — it read the finished shell with bashoutput, or stopped it with killbash.

A slow foreground command is moved, not killed. timeout defaults to 60 seconds and is capped at 10 minutes. If a command is still running when its timeout expires, it is handed to a background shell with the output it has printed so far, and the agent is told its id — the run continues and its exit is reported as above. The one exception: when the agent set timeout itself below the cap, it meant “stop it then”, so the command is killed and the agent sees the partial output.

Watching a run as it happens: monitor. A background shell reports once, at exit. monitor runs a command in the background and sends the agent a notification for each batch of output lines while it runs — or only the lines matching a pattern, e.g. FAIL|Error|Traceback. So “run the eval and tell me the first failure” gets an answer at the first failure, not three hours later. Lines arriving within a second are one notification; a monitor stops itself after 20 notifications (the filter was too loose) or after timeout_ms (default 5 minutes, at most 60), and sends a final notification when it ends. It needs notifications on, and its permission rules match on the command exactly like bash’s (Monitor(pnpm eval:*)).

A monitor can also watch a background shell that is already running: pass its bash_id instead of a command. Output printed before it attached is checked too. When it hits a limit it stops watching and leaves the shell running, and the shell’s own exit notification reports the end. Attaching starts no new command, so it has its own rule, Monitor(bash_id:*), which never approves a command.

SettingEffect
tasks.notify: false in settings.json, or FREECODE_TASK_NOTIFY=0No notifications, so no turn ever starts without you. Background shells still run; the agent has to check them with bashoutput. monitor is unavailable.

When a background task is stopped early. Shells die with their session and with FreeCode itself — a command that must outlive the session belongs in your own terminal. What changes is that the agent is told: when you resume a session whose background tasks were stopped before finishing (you switched away, FreeCode restarted or crashed), you see a notice listing them, and the agent is told on your next message instead of waiting for a result that cannot come. Resuming never starts a turn by itself.

On this page (coming soon)

  • File operations: read, write, edit, ls
  • Search and code intelligence: glob, grep, lsp
  • Execution and delegation: bash, agent
  • Web access: webfetch, websearch
  • Workflow: skill, todowrite, question, output, memory
  • Parallel vs sequential execution, and why it matters
  • Per-tool parameters — see the tools reference