(^、^7 gatto — an AI assistant that runs on your own PC

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.

  1. Finds the engine. Running a model needs llama.cpp underneath, 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.
  2. 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.
  3. 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.
  4. 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 i is 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 --continue resumes the last conversation in this folder.
  • gatto --continue <id> resumes a particular one.
  • /new starts 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 file
  • write_file — write a new one
  • edit_file — change part of one, leaving the rest alone
  • glob — find files by name
  • grep — search inside files
  • shell — 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 first writes 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 .gguf you 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 .csx file into that folder, keeping its name, and restart gatto. A one-command install is coming.
  • Remove — delete the file. Nothing else remembers it.
  • Checkgatto doctor compiles every script and reports the ones that fail; /tools shows 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.

GGitHub XX BBluesky MMastodon RReddit Windows 10 / 11 GPL-3.0
  /l、
(^、^7   zzz
  l  ~ヽ
  じしf_,)ノ

nothing here yet — a game goes in this space

Close gatto.computer
(^、^7

Are you sure you want to close this window?

It's now safe to close
this tab.
…or come back.