Tools

Which of the built-in tools the agent gets, and how to give it your own — a script you run often, or an API you want it to call — without writing a server.

Settings → Tools. Two tabs across the top: Native Tools, the tools the agent ships with, and Custom Tools, the ones you add yourself.

Native tools#

Every conversation starts with the same catalogue, grouped as Files (read_file, read_files, list_dir, create_dirs, write_file, edit_file, delete, move_path, copy_path), Code (code_search, code_grep, symbols, references, check_errors) and Shell (run_command). Each has a switch, and a counter in the corner reads N off with an Enable all button beside it.

Switching one off does two things. The model is not told the tool exists, so it will not try to use it. And if a model remembers the name from an older conversation and calls it anyway, the IDE refuses and tells it so. Switching it back on takes effect on your next message; there is nothing to restart.

You cannot switch off the tool that ends a turn. A turn with no way to end is not a smaller toolset, it is a hang.

Memory#

Each native tool also has a memory switch. Every tool call is written to the conversation on disk with what it returned; the memory switch says whether the agent's memory reads it: when it is on, the agent can find that tool's calls when it searches past conversations, and the memory walker sees them when it writes the conversation down. It is off for every native tool until you say otherwise, because most of what these tools return is the codebase passing through, and the code index already knows the code. The one people turn on is run_command, so the things a script printed are remembered.

The switch is read when memory looks, not when the call is made, so turning it on later covers the whole history. A remembered tool call is cut to a few thousand characters where it is shown.

The agent's own memory tools are not on this page and have no switch. What it writes with them — a memory it carves, a note to its crew, a standing order it pins — is its own words and is always remembered, in full. What it reads back with them is memory already, and is never remembered again.

Stored per machine, in ~/.semantix/USER/agent-tools.json, as the list of names you turned off and the list you asked memory to read. A native tool added in a later release is on, and not remembered, by default.

Custom tools#

A custom tool is something you write once and the agent calls by name, with arguments it fills in from your description. The form is always open at the top of the tab — there's no Add button. Create saves it and hands you a fresh blank form; Cancel just clears it. Below the form, your tools are listed with a ws or usr badge for their scope, their kind, and their parameter names; Edit swaps a row for its form.

Two kinds, chosen with the Bash / HTTP toggle beside the name — and fixed once the tool is created:

Bash — a script. One command or several lines; pipes, && and redirects all work, because you wrote it, not the model. Every parameter you declare reaches the script as an environment variable with the same name in capitals: a parameter called branch is $BRANCH. The script runs in the workspace root — or the Working directory you set, relative to it — as bash -lc, so your usual PATH is there: the same nvm, cargo and conda your terminal sees. The Shell field lets you name another shell; Timeout ms defaults to 60,000.

Name         deploy_staging
Description  Deploy a branch to the staging server and print its URL.
Parameters   branch  (string, required)  The branch to deploy, without refs/heads/
Script       git push staging "$BRANCH":main
             ./scripts/announce.sh "$BRANCH"

The agent sees it as deploy_staging(branch). When it calls it, the card in the chat is the same command card run_command uses, with a Stop button while it runs and the output behind a chevron once it's done.

HTTP — an API call. Method, URL, Headers and an optional Body, with {{name}} wherever a parameter goes. Values dropped into the URL are URL-encoded; a JSON body is rendered as JSON, so "{{count}}" becomes the number 3 and a string with quotes in it can never break the document. The request is made by Semantix on your machine, so the headers — your API key — never leave it, and there is no browser cross-origin rule in the way. Timeout ms defaults to 30,000.

Name         weather
Description  The forecast for a city, N days ahead.
Parameters   city (string, required) · days (number)
Method/URL   GET  https://api.example.com/forecast/{{city}}?days={{days}}
Headers      X-Api-Key  ····

The card shows GET …/forecast/Haifa?days=3 → 200 · 140 ms, and the response body is under the card's output expand, which is also exactly what the model read.

A {{placeholder}} that names no parameter blocks the save, and the form says which one.

Trying it before you save#

Beside the form is a bench with two panes. The top pane shows what will run, as you type: for a bash tool the bash -lc line, the environment your parameters become and the script; for an HTTP tool the request line with the values already encoded into the URL, the headers (a key is masked) and the body as it will be sent. Each parameter gets a sample-value field above it; the preview re-renders as you fill them, using the same renderer the agent's call uses, so what you see is what the model's call will produce.

Test now runs the tool once with those sample values. A bash tool streams into a live terminal in the bottom pane, with a Stop button, and settles to its exit code and output; an HTTP tool shows GET … → 200 · 140 ms and the response body. Nothing is saved by testing, and no approval card is raised — you are running your own tool by hand. While the form is incomplete the button is disabled, and the bench says what's missing: Give the tool a name. Write the description. The script is empty.

Parameters#

Each parameter has a name, a type (string, number or boolean), whether it is required, and a one-line description. The description matters more than it looks: it is what the model reads to decide what to put there. "The branch to deploy, without refs/heads/" gets you main; an empty description gets you whatever the model guessed.

A parameter marked optional that the model leaves out arrives as an empty string in a bash tool and renders as nothing in an HTTP template. A required one it leaves out is refused before anything runs, and the model is told which one was missing.

Danger level#

A custom tool does not say whether to ask. It says how dangerous it is, and the permission mode you picked next to Send — Manual, Edits or Full — decides whether that level asks, the same way it decides for the built-in tools.

Level Like Asks in
None a read never
Edits a file write Manual
Critical (default) a shell command Manual and Edits

When it does ask, the card is the same approval card the built-in tools use, badged CUSTOM TOOL, and For session covers it like any other class. Tools saved before this existed are read as the nearest level: "Ask first" became Critical, "Run automatically" became None.

→ Asking permission

Memory#

Memory is on for a custom tool unless you switch it off: you wrote the tool, so what it returns is usually the point, and the agent can find its calls when it searches past conversations and the memory walker reads them. Switch it off for a tool whose output is noise, such as a build log. Same rule as the native switch: read when memory looks, so a change covers the whole history.

A bash tool also takes the turn's workspace checkpoint before it runs, so Restore covers whatever the script changed.

Names#

Lowercase letters, digits and _, starting with a letter, up to 64 characters — a function name to every model. A custom tool cannot take a native tool's name, and cannot start with mcp__; the save tells you if it collides. The name can't be changed afterwards; to rename, delete and recreate.

Where they live#

User tools are files under ~/.semantix/USER/tools/<name>.json and apply in every project on this machine. Workspace tools are under ~/.semantix/WORKSPACE/<project-id>/tools/ and apply only in that project; with no project open, the Workspace option is greyed out. When both scopes have a tool of the same name, the workspace one wins. The files are plain JSON; you can edit them by hand, and a file that does not parse is skipped with a warning rather than hiding the rest.

Changes apply on your next message. There is no restart, and no need for a new conversation.

What this is not#

MCP. An MCP server is somebody else's tool catalogue; you connect it under MCP servers and everything it exposes arrives as mcp__<server>__<tool>. A custom tool is yours — one script or one endpoint you already know how to call. If the thing you want already speaks MCP, connect it there instead of describing it again here.

Agents. A custom tool cannot start another agent or call a model. That is a different feature, with a different set of questions about cost, and it is not in this one.