Manual
Everything gatto does, in one page. If you are starting from nothing, read straight down: this begins at the download and ends with an installed, working setup.
Getting gatto
gatto is one file. There is no installer, no setup program, and nothing is added to your
system outside a single folder you can delete. Download gatto.exe, put it
somewhere you can find it — your Desktop is fine, so is a tools
folder — and that is the install.
It runs on Windows 10 and 11, 64-bit. It is free, and its source is on GitHub under the GPL.
Putting it on your PATH (optional)
If you want to type gatto from any folder rather than pointing at the
file each time, put the folder containing it on your PATH: Settings → System → About → Advanced
system settings → Environment Variables, edit Path under your user
variables, and add the folder. Open a new terminal afterwards — an already-open one keeps the
old PATH.
The first launch, and the warning you will see
The first time you run it, Windows will show a blue box saying “Windows protected your PC”. Choose More info, then Run anyway.
This happens because gatto is not code-signed. A signing certificate is an annual fee paid to a certificate authority, and gatto does not have one — so Windows has no receipt to check and says so. The warning is about the absence of a receipt, not about anything found in the file. If you would rather verify it yourself, build it from source: the repository is public.
After that first time, Windows remembers and stops asking.
Setting it up
Run gatto with no arguments. On a machine that has never run it, it
offers to set itself up; you can also start the wizard directly with
gatto setup.
The wizard does four things, and asks you before each one that matters.
- Finds the engine. Running a model needs
llama.cppunderneath, and there is a different build of it for each kind of graphics card. gatto looks for one you already have, and offers to fetch the build that matches your hardware if you do not. - Finds a model that fits. It reads how much memory your graphics card has, does the arithmetic, and offers you models that will actually run on it. You choose from what fits.
- Writes the configuration — at the end, not before. Every answer you give is held until the last screen. If you close the window halfway through, nothing has been written: no folders, no settings, no half-finished state to clean up.
- Shows you that it works. With everything in place, gatto asks your new setup a question and shows you the answer. You see it work before you are handed the prompt.
It will also offer to check that the model can use tools, which is worth saying yes to the first time you set one up.
What it writes, and where
Everything gatto creates lives under ~\.gatto\ — that is
C:\Users\<you>\.gatto\. Nothing goes into Program Files, the registry,
or anywhere else.
~\.gatto\
gatto.json your settings: which endpoint, which model by default
GATTO.md notes gatto reads at the start of every session
models\ one folder per model setup you have added
roles\ generalist.json, coder.json, oracle.json
extensions\ the scripts that give gatto extra tools
agents\ definitions for the subagents it can hand work to
sessions\ a transcript per conversation
Adding a second model later, moving weights somewhere with more room, and pointing gatto at files you already have are covered under serving a model.
The command line
gatto is one executable with a small surface:
gatto [role|command] [options]
roles: generalist (default) | coder | oracle | any ~\.gatto\roles\*.json
commands: setup
serve start [model] [--detach] | serve stop | serve status
doctor | status
audition
model new [gguf] [id]
uninstall
options: -m <model> -p <prompt> --continue[ <id>] --yes --auto --version -h
The most common ways to start it:
gatto— a session in the generalist role, in the current folder.gatto coder— a session in a different role. Any file in your roles folder is a valid word here.gatto -p "what does this project do?"— one question, one answer, and it exits. Useful in a script.gatto --continue— pick up the last conversation in this folder instead of starting fresh.
The folder you start gatto in is the project it works on. It reads and writes files underneath that folder, and permissions you grant are remembered per project.
Checking it works — gatto doctor
gatto doctor looks at your setup and prints one line per check. Every
line that is not a tick tells you what to do about it. Run it whenever something behaves oddly; it
changes nothing, so it is always safe.
gatto · doctor · v0.4.0 ✗ server reachable: http://127.0.0.1:1235 unreachable — run: gatto serve start my-model ✓ gatto.json parses (C:\Users\you\.gatto\gatto.json) ✓ models: 1 model(s) under C:\Users\you\.gatto\models all consistent ✓ roles: 3 role(s) under C:\Users\you\.gatto\roles all valid ✓ extensions: 3 script(s) compile ✓ llama_server: C:\Users\you\llama.cpp\llama-server.exe (version: 10076) ✓ permissions.json: not present (skipped) ✓ context files: 1 loaded for ~\projects\thing ✓ no .gatto.json on the walk ✓ memory: enabled — 0 facts, index budget 1000 tokens i updates: couldn't reach GitHub just now
What each row is telling you:
- server reachable — is the model actually running and answering? This is the one that is red most often, and the fix is nearly always to start it.
- gatto.json — your settings file parses. If this fails, most of the rows below it cannot be computed and will say so rather than guess.
- models / roles / extensions — the things in your home folder are present and valid. Extensions are actually compiled here, so a broken script is caught before a session needs it.
- llama_server — the engine is where the configuration says it is, and it reports its version.
- permissions.json, context files, memory — what this project has granted, what gatto will read at launch, and whether it is keeping notes.
- no .gatto.json on the walk — no folder between here and the drive root is trying to configure gatto. A project cannot reconfigure your assistant.
- updates — whether a newer gatto exists. An
iis information, not a problem.
A few rows only appear when they apply — a Downloads folder that has been moved, a project that has switched auto-compaction off, more than one server answering. If you do not see them, there is nothing to see.
gatto status is the shorter one: where home is, which endpoint and model
are configured, and how many sessions this project has.
Checking a model can do the job
A model that writes well and cannot reliably call a tool is no use as an assistant, and nothing
on a model's description page tells you which one you have. gatto audition
finds out: a fixed set of tasks, run through gatto's real agent loop with its real tools, marked
mechanically. No second model judging the first, and no opinion — each task either worked or
it did not.
The setup wizard offers this for a model you have just added. You can also run it whenever you like:
gatto audition my-model
A model that passes carries the note tool-calling verified with the
month it was checked. ⚠ That is a statement about one thing only. It does not say a model is good,
or fast, or better than another one — a model can pass this and still be poor at the work you
actually want done.
When something is not working
Run gatto doctor first. Most problems show up there with the fix
written on the line.
It says the server is unreachable
The model is not running. Start it with gatto serve start, or set gatto
to start it for you automatically — see serving a model. If it still
cannot connect after starting, check that nothing else on your machine is using the same port.
It starts, then fails partway through a first run
Setup writes nothing until its last screen, so a failed run leaves nothing behind and you can
simply run gatto setup again. If a download was interrupted, run it again
— it will pick up what is missing.
Answers are extremely slow
Usually the model does not fit in your graphics card's memory and part of it is running on the
CPU instead. gatto doctor will tell you what is configured; the fix is a
smaller model, or a more compressed version of the same one.
The model answers, but never uses any tools
Some models cannot reliably call tools at all. gatto audition is the
way to find out for certain rather than guessing from behaviour.
Something is wrong that is not on this list
Open an issue on GitHub with what you ran, what
you expected, and what happened — and paste the output of gatto doctor
if you can. It answers most of the questions anyone would ask you first.
Uninstalling
gatto uninstall walks you through it: it shows you what exists, asks what
should go, and removes only what you say yes to.
If you would rather do it by hand, there are exactly two things:
- Delete
gatto.exe, wherever you put it. - Delete the folder
~\.gatto\, which holds your settings, models, roles, extensions and session transcripts.
⚠ The models are the big part — each one is gigabytes. If you might come back, keeping
~\.gatto\models\ and deleting the rest saves re-downloading them.
Nothing else was touched. There are no registry entries to clean up, no services left running, and nothing in Program Files. If you added the folder to your PATH, remove it there too.
A session, and what it is attached to
Run gatto in a folder and you get a prompt. That folder is the project:
everything gatto reads or writes is underneath it, permissions you grant are remembered for it, and
the conversation is saved against it.
Type a question and press Enter. gatto answers, and calls whatever tools it needs along the way — you see each one as it happens.
gatto --continueresumes the last conversation in this folder.gatto --continue <id>resumes a particular one./newstarts over without leaving./quit, or Ctrl+C twice, exits.
Rich mode and plain mode
In a normal terminal gatto takes over the screen: a live status line, tool calls that update in place, thinking you can fold away. If output is being piped somewhere, or the terminal cannot support it, gatto drops to plain mode and prints ordinary lines instead. You do not choose; it notices. Everything works in both — plain mode is a different surface, not a reduced one.
The screen
Top to bottom, a session looks like this.
- The banner — the cat, then gatto's version, the role you are in, and the model you are talking to. The cat changes with the role.
- The transcript — your messages, gatto's replies, and every tool call in between.
- The gutter — the narrow column of marks down the left.
❯is you,○is a tool being called,●is gatto speaking. It is there so you can scan a long transcript without reading it. - The status line — at the very bottom: which folder, which model, whether thinking is on, tokens sent and received, and how full the context is.
Thinking, folded
Models that reason before answering show a collapsed line rather than the whole train of thought.
Expand it with Ctrl+R; move between foldable blocks with
Ctrl+↑ and Ctrl+↓. The reasoning is kept, not
discarded — it is just not in your way.
The purr
While gatto is working, the cat's face animates and a line below it counts what is happening. On a local model an answer is not instant, and a still screen is indistinguishable from a hung one. When the turn finishes, the purr line is replaced by what it cost: how long, how many tokens.
Typing
The prompt is a real line editor, not a raw read.
- Arrow keys move within the line; Home and End jump to its ends.
- Ctrl+← and Ctrl+→ move a word at a time.
- ↑ and ↓ walk your history — the things you typed before, in this project.
- Enter sends. A multi-line paste stays multi-line rather than sending on the first newline.
- Ctrl+C cancels the turn in progress; twice in a row exits.
Typing while gatto works
You do not have to wait. Anything you type during a turn is held and sent when that turn ends, so a thought that arrives mid-answer does not have to be remembered until the prompt comes back.
Showing gatto a picture
Paste an image straight into the prompt. It is attached to your next message and shown in the
transcript as [Image #1], so you can refer to it in words. Whether it is
understood depends on the model: a model without vision receives the message without the picture,
which is worth knowing before you conclude it ignored you.
What gatto can actually do
Six tools are built in:
read_file— read a filewrite_file— write a new oneedit_file— change part of one, leaving the rest aloneglob— find files by namegrep— search inside filesshell— run a command and read what it printed
That is a deliberately short list. Nearly everything you would want done to a project is one of those six, and a smaller model chooses better when it has fewer things to choose between.
Others arrive depending on your setup: the two memory tools when memory is
on, run_agent for handing work to a second copy of gatto, and whatever your
extensions add — including the three that ship with it,
ask_user, web_search and
web_fetch. ⚠ Those three are bundled extensions, not built-ins: they
live in your extensions folder like any other, and you can read or remove them.
/tools lists exactly what is armed in the session you are in, which is
the only answer that is true for your machine.
Permission
Reading is free. gatto reads files, searches and lists without asking, because none of it changes anything.
Anything that writes or runs stops and asks. That is write_file,
edit_file and shell. You see what it wants to do
— the actual command, the actual path, the actual content — before it happens, and you
answer:
- Yes — once, this time.
- Always — for this kind of thing in this project, from now on.
- No — and you can say why, which gatto reads as part of the conversation.
Standing grants are per project and are kept in that project's own
permissions.json. /permissions lists them;
/permissions revoke <n> takes one back. Nothing is granted globally
and nothing is granted forever by accident.
Checkpoints
Some roles turn on an extra pause before anything is committed to version control: gatto shows you
the commit it is about to make and the state of your working folder, and waits. ⚠ That pause cannot
be granted permanently — it asks every time, by design. /auto toggles
auto-approval for the ordinary prompts, not for this one.
Turning the prompts off
/wild — or Shift+Tab — runs without
prompts and without checkpoints. It is there for when you are watching, the work is repetitive, and
being asked forty times is worse than the risk. ⚠ It means what it says: gatto will write and run
things without asking. Use it in a folder you would not mind restoring, and turn it back off.
What a project cannot do
gatto loads extensions from your home folder only, never from the project. A repository you have
just cloned cannot arm a new tool, cannot grant itself a permission, and cannot reconfigure gatto by
leaving a file lying around. gatto doctor checks for that last one by name.
Slash commands
Fourteen, all typed at the prompt. /help prints this same table.
/help show this table /new reset the conversation /role [name] show or switch role /model [name|add] show or switch the model, or add one /effort [level] show or set thinking effort /think [on|off] toggle reasoning (toggle-only models) /compact summarize + shrink context /auto toggle checkpoint auto-approve /remember <text> bank a note to project memory, in the model's own words /wild [always|never] no prompts, no checkpoints (Shift+Tab toggles) /permissions [all|revoke <n>] review + revoke standing permission grants /tools list the tools armed this session /init survey the project, write GATTO.md /quit exit
Three of them go through the model rather than acting locally —
/compact, /remember and
/init — so they take a moment and cost tokens, like any other turn.
Context, and what happens when it fills
A model can only hold so much of a conversation at once. The status line shows how full that is. As it fills, gatto trims the oldest tool output first — the results, not your messages and not what gatto said — because a directory listing from forty turns ago is the cheapest thing to lose.
When trimming is not enough, /compact asks the model to summarize the
conversation so far, then continues from that summary with the detail dropped. You keep the thread;
you lose the transcript. It also banks anything worth remembering into
project memory on the way past.
In an interactive session this happens on its own when the context gets close to full. In a
one-shot run (-p) it never does — a script gets trimming only, so its
behaviour cannot change halfway through on you.
Notes for the project — GATTO.md
A file called GATTO.md in your project is read at the start of every
session. It is where you put the things you would otherwise say every time: what this project is,
how to run its tests, which conventions matter, what not to touch.
gatto walks up from your folder collecting them, so a note at the top of a repository applies to
every folder inside it, and one in a subfolder adds to it. A GATTO.md in
your home folder applies everywhere.
/init writes a first draft for you: gatto reads the project and produces
a GATTO.md describing what it found. Read it before trusting it — it
is a starting point, and you are the one who knows what actually matters.
Memory — what carries between sessions
A new session starts with no recollection of the last one. Memory is the exception: short facts, kept per project, that gatto reads at launch.
It banks them in three ways:
- On its own, when something in the conversation is worth keeping — a convention, a decision, a thing that turned out to be true.
- When you say so:
/remember the tests need the server running firstwrites it in gatto's own words rather than storing your sentence verbatim. - During
/compact, which banks as it summarizes.
What it has is loaded into the conversation at launch as a short index. gatto can pull the full text of any fact when it needs one.
⚠ A fact you bank is in play from the next session, or from /new —
not in the middle of the turn that wrote it. That is deliberate: rewriting what the model has already
been told, mid-conversation, would cost a local model a full re-read of everything.
The facts are plain files under your project's .gatto\memory. Read them,
edit them, delete them. To switch memory off entirely, set "memory" to
false in gatto.json;
gatto doctor reports which it is.
Subagents get neither memory tool — they do a job and report back, and are not the thing that accumulates knowledge about your project.
Handing work to a subagent
run_agent starts a second, fresh copy of gatto on one task, and returns
only its final answer.
The point is your context. A job like "find every place this function is called and summarize what they do" produces a great deal of reading and one paragraph of conclusion. Done in your session, all that reading stays in the conversation and crowds it. Done by a subagent, only the paragraph comes back.
Subagents are defined by files in ~\.gatto\agents\ — each names what
the agent is for and which tools it may use. They run one level deep: a subagent cannot start another
one.
Sessions
Every conversation is written to a file as it happens, under
~\.gatto\sessions\. Nothing is uploaded; the transcript is on your disk and
that is the only copy.
That is what --continue reads. It is also a plain-text record you can
search, keep, or delete — deleting a session file removes the conversation and nothing else.
⚠ You may occasionally see a note that gatto removed some stray control tokens from a model's output, once per session. Some models emit fragments of their own prompt formatting into the text they produce; gatto strips a short, known list of those so they do not end up in your files. It is a tidy-up, not an error, and it says so once rather than every time.
Using gatto in a script
gatto -p "<question>" runs one turn and exits, printing the answer to
standard output. Combined with --yes it does not stop to ask about anything,
which is what makes it usable unattended — and worth thinking about before you point it at
something that matters.
The exit code tells the caller what happened:
- 0 — it ran.
- 1 — something failed while running: the model was unreachable, a tool threw, the turn was cancelled.
- 2 — it never got started: a bad argument, or a configuration file that would not load. Fix the invocation, not the environment.
The distinction is the useful part: 2 means try a different command, 1 means try again.
Roles and role files
A role is a JSON file in ~\.gatto\roles\. It sets what gatto is told
about how to behave, which checks it has to satisfy, and which model it uses. Three ship;
the roles page covers what each one is for.
/role shows the current one, /role coder
switches. On the command line, the role is just the first word:
gatto coder.
What a role file can carry
{
"append": "extra instructions, added to what gatto is told",
"checkpoints": true,
"gates": ["grounding", "citations"],
"model": "a model setup this role should use",
"sampling": { "temperature": 0.3 },
"thinking": "on"
}
Every key is optional, which is why the generalist's file is {} and
still a valid role. Add a file, and the name is available immediately — nothing is registered
or compiled, and gatto doctor will tell you if a file will not parse.
The two checks a role can turn on
- grounding — pushes back when gatto states something about your project that it has not actually read. It nudges rather than blocks: the reply still arrives, with a reminder attached that the claim was not checked.
- citations — asks gatto to say where a claim came from, and keeps a record of every page it fetched during the session.
Both are on for the oracle role and off for the other two, because they cost tokens and are worth it when the output is research rather than code.
Model setups
A model setup is a folder under ~\.gatto\models\ that names one
model and how to run it: where its file is, how much context to give it, how it should be sampled.
It is not the model itself — the weights can live anywhere.
The setup wizard writes your first one. After that:
/model— show which one is armed./model <name>— switch to another, without leaving the session./model add— add one from inside a session.gatto model new <file.gguf> <name>— make a setup from a.ggufyou already have on disk.
⚠ Switching model mid-session means the new model has to read the whole conversation before it can add to it. gatto warns you and asks first, because on a local model that is not free.
A setup's own file is profile.json inside its folder. Useful keys:
model_path where the .gguf actually is context how many tokens of conversation to allow gpu_layers how much of the model to put on the graphics card sampling temperature and friends mmproj the vision file, for models that can see images extra_args anything else to pass the engine llama_server a specific engine build, if this model needs one
Serving a model
A local model runs as a small server on your machine, and gatto talks to it over the loopback address. Nothing listens outside your computer.
gatto serve start <model> start it gatto serve start <model> --detach start it and return the prompt gatto serve status is it running, and with what gatto serve stop stop it
Letting gatto start it for you
Set "auto_serve": true in a model's setup and gatto starts the server
when a session needs it, instead of telling you to. This is the setting most people want; the wizard
offers it.
Moving the weights somewhere with more room
Model files are large and your system drive may not be where you want them. The weights are
wherever model_path says — move the file, update that one line, and
gatto follows. Nothing else refers to the location.
Locking the server down
Set "api_key" in the setup and the server will refuse requests that do not
present it. Worth doing if you run other software on the same machine that scans local ports; not
necessary otherwise, since the server is already bound to loopback only.
Settings — gatto.json
One file, ~\.gatto\gatto.json, holding the things that are true for every
project.
{
"endpoints": {
"local": { "base_url": "http://127.0.0.1:1235" }
},
"default_endpoint": "local",
"default_model": "my-model",
"memory": true
}
An endpoint is somewhere gatto can talk to a model. The local one is a server on your own
machine. You can add others — a hosted API is an endpoint with a
base_url and an api_key — and switch with
/model. gatto is local-first, and it does not stop you.
If this file will not parse, gatto doctor says so and every check that
depends on it reports cannot determine rather than guessing. Fix this one first; the rest
usually follow.
⚠ A project cannot override these. gatto deliberately does not read settings from the folder you opened, and doctor checks that no folder on the way up is trying to.
Extensions
An extension is a C# script that gives gatto a new tool. They live in
~\.gatto\extensions\, are compiled at launch, and come from your folder
only — never from the project you have open.
- Install — save the
.csxfile into that folder, keeping its name, and restart gatto. A one-command install is coming. - Remove — delete the file. Nothing else remembers it.
- Check —
gatto doctorcompiles every script and reports the ones that fail;/toolsshows what a session actually armed.
The extensions page lists the ones that ship, with their full source; writing one documents the host API.
Why an edited copy can behave differently
Some bundled extensions are trusted with slightly more access than a script you wrote yourself
— ask_user is one, which is why it can interrupt you without asking
permission first. That trust is not attached to the name; it is attached to the exact contents of
the file, checked against the copy compiled into gatto.
So: change one byte and it becomes an ordinary script. It still runs, and it still works — it just loses the extra access and starts asking permission like anything else. Rename it, or nest it in a folder of its own, and the same thing happens. ⚠ This is worth knowing because nothing errors when it happens: the tool simply does a little less than it used to, and the reason is not on screen.
The web tools
Two of the bundled extensions let gatto reach the internet:
web_search looks things up, and web_fetch reads a
page and hands back its text.
⚠ These are the only tools that send anything off your machine, and they are
permission-gated per project like any other command — even though they ship with gatto. If you
never say yes, nothing leaves. Delete
web_search.csx and the capability is gone entirely.
Where the results come from
Searching tries a chain of providers in order and stops at the first that returns anything. The
default needs no account. Others can be configured in gatto.json under a
"search" section — the supported names are
ddg, tavily and
searxng; the last two want a key or a server address of your own.
When the citations check is on, gatto keeps a record of every page it fetched during a session, beside that session's transcript.
Where everything lives
All of it is under ~\.gatto\, and all of it is plain files you can read
and edit.
~\.gatto\
gatto.json settings: endpoints, the default model, memory on or off
GATTO.md notes read at the start of every session, everywhere
models\ one folder per model setup, each with a profile.json
roles\ generalist.json, coder.json, oracle.json, and yours
extensions\ .csx scripts, compiled at launch
agents\ subagent definitions
sessions\ one transcript per conversation
<your project>\
GATTO.md notes for this project
.gatto\
permissions.json what you have granted here
memory\ facts gatto has banked about this project
Two things follow from that shape, and they are the whole design:
- What gatto can do is decided in your home folder. Tools, roles, models — a project you open cannot add to any of them.
- What gatto has learned is decided per project. Permissions and memory live with the work they belong to, and do not follow you to the next folder.
To remove gatto entirely, delete this folder and the executable. See uninstalling.