Setting up
Installing gives you the binary. This page gets it to the point where it can actually answer — a provider it can reach, settings that match what is really being served, and whatever personal context you want it to have.
If you read one thing here, read mecha setup below. Most of
what goes wrong at this stage goes wrong quietly, and that command exists to
make the quiet part loud.
1. Check the install, before any credentials exist
mecha tools deliberately does not build a provider. You should be able to see
and debug your tool surface before any credentials exist, and a broken MCP
server should be diagnosable without spending a token.
mecha tools
It lists every tool an agent would see right now, prints the active sandbox backend, and — because it connects to configured MCP servers — doubles as a check that those servers actually start.
Two flags are worth knowing:
mecha tools --schema # the full JSON schema for each tool, exactly as the model sees it
mecha tools --json # machine-readable, including each tool's declared capabilities
The --json view is the auditable one. shell declaring external_send: false
is a claim the sandbox is making on its behalf, and it should be inspectable
without reading source.
On a fresh install you should see the built-ins: fs_read, fs_write,
fs_edit, fs_list, shell, http_fetch, todo, and goal_context. web_search is absent
until a search backend is configured, because a search tool that always errors
is worse than no search tool.
2. Point it at a model
mecha config init # writes ~/.mecha/config.toml
config init writes a commented starter file rather than a dump of defaults,
because the point of the file is to show what is adjustable. The default is a
model on this machine, never a hosted one, so a prompt is answered here unless
you choose a provider that sends it elsewhere. The provider blocks it writes:
default_provider = "local"
[providers.local]
kind = "local"
base_url = "http://127.0.0.1:8080"
[providers.anthropic]
kind = "anthropic"
model = "claude-opus-5"
api_key_env = "ANTHROPIC_API_KEY"
A local model (the default)
mecha setup asks about this first (step 3 below). On Linux, choosing the
recommended model — or mecha setup chat on its own — installs everything
the default needs: llama.cpp,
the model recommended for this machine's memory (or a GGUF you already have),
and the router that serves it on :8080. It then reads the model's settings
off the server and writes them into [providers.local]:
mecha setup chat
A server you already run on :8080 is left alone; mecha setup --write reads
its settings into the config instead.
Anthropic
export ANTHROPIC_API_KEY=sk-ant-...
mecha run -p anthropic "..." # one run; or set default_provider = "anthropic"
Whatever a run sends — your files, mail, notes — then goes to Anthropic.
api_key_env names an environment variable. There is also an api_key field
that takes the key inline; prefer the variable, because the inline form puts a
credential in a file on disk.
Model ids are exact strings with no date suffix.
Another OpenAI-compatible server
Anything speaking /v1/chat/completions works: llama-server, vLLM, Ollama, or a
hosted API. Point [providers.local] at it, or add another provider entry —
providers merge by key, so a project file can add an endpoint without restating
the others.
[providers.local]
kind = "local" # "local", "openai", "openai-compatible" — same backend
base_url = "http://127.0.0.1:8080" # no /v1 suffix; the path is appended
model = "qwen3-14b"
context_window = 32768 # per slot — not `-c`. See below.
vision = true # only if the server has a projector loaded
Do not type those last three by hand. Each is a setting nothing can check afterwards, because each degrades quietly rather than failing — which is what the next step is for.
A new entry under another name is selected by making it the default:
default_provider = "my-server"
or per run:
mecha run -p my-server "..."
export MECHA_PROVIDER=my-server # or via the environment
Naming a provider or a model — -p, --model, MECHA_PROVIDER,
MECHA_MODEL — pins it. On a llama-server router with follow_loaded set
(see the configuration reference), a pinned run uses the named entry rather
than whichever model is loaded, so leave these unset in a shell profile if
you want mecha model use to be followed.
3. mecha setup
mecha setup
On a fresh install, at a terminal, setup walks through everything in one pass and asks before it downloads anything:
- The chat model. If something already answers on
:8080, setup offers to write down what it serves. Otherwise it offers the model recommended for this machine's memory, a GGUF you already have, or a hosted model (Anthropic, withANTHROPIC_API_KEYset in your shell). The local model installs on Linux as a systemd user service and on a Mac as a launchd agent. - Each optional feature, one at a time: what it does, what it downloads,
and
y,Nornever. A feature that needs another says so. - One summary and one
Start?: everything you said yes to and the total download. Nothing is fetched or switched on before that yes. - Sign-ins. Google Docs opens its sign-in page in your browser straight
away. Mail and calendar first walk you through registering your own
sign-in app, once (see
Mail and calendar), then open
theirs. Slack takes its two tokens from your shell (
mecha slack auth). Mail, documents and the graph also need an[[mcp]]entry in~/.mecha/config.toml; setup names it and does not write it, so add the entry (see §4) and the sign-in runs on the nextmecha setup. - Whatever is still open, with the command for each.
What it looks like, trimmed:
Chat model
1) Use the recommended model: <the model for this machine> (<size> download)
2) Use a GGUF I already have
3) Use a hosted model instead (Anthropic — needs ANTHROPIC_API_KEY)
4) Skip for now
Which? [1]
Features — enable each? (all can be changed later with `mecha features`)
Mail and calendar
Mail and calendar, behind one server that names an account, never a provider.
Enable? [y/N/never] y
Google Docs, Sheets and Slides
Google Docs, Sheets and Slides — only files it made or you hand it in Google's picker.
Enable? [y/N/never] y
Image generation (16.8 GiB download)
Making pictures on a local image server, with a character and style library.
Enable? [y/N/never] n
…
Start? [Y/n]
Your charter is the one thing setup never writes for you and never opens an
editor for: it says where to write it (mecha charter edit, or Settings →
Charter in the web app) and carries on.
Run without a terminal (piped, or from a script), setup only reports. It prints what this install still needs with the one command that fixes each, and exits 1 while anything is outstanding:
! The config disagrees with what is served [disagrees]
[providers.local] context_window = 32768, but the server is serving 262144
tokens per slot. The server has 4 slots and divides `-c` evenly across them,
so the value to write down is `-c / 4` and not `-c`. …
→ mecha setup --write
· Mail and calendar [not set up]
Mail and calendar, behind one server that names an account, never a provider. Off until it is switched on.
→ mecha features enable mail
· Google Docs, Sheets and Slides [not set up]
Google Docs, Sheets and Slides — only files it made or you hand it in Google's picker. Off until it is switched on.
→ mecha features enable docs
· Your charter [not set up]
Nothing written yet — every run is proceeding un-chartered. …
4 step(s) outstanding.
--json prints the same plan and never prompts. For a local provider, setup
always asks the server what it is actually serving and compares that with
your config, as the first entry shows.
Letting it write the settings
mecha setup --write
This rewrites model, context_window and vision from what /props
reports. It shows you the values first and asks before touching anything, keeps
the previous file as config.toml.bak, and edits the table in place so your
comments survive.
:::tip Why this is a command and not a paragraph of documentation
All three of these settings were documented correctly for months while the
machine that wrote the documentation had two of them wrong. None of them
fails when wrong — a bad context_window makes a long run compact at a
threshold nobody chose, an unset vision makes every screenshot arrive as a
line of text, and a wrong model changes only what your session records claim
answered. Reading them off the wire is the only way to be sure, which is why
the command asks the server instead of asking you.
:::
The same comparison runs at startup on every command, so if the two drift apart later you hear about it the next time you use mecha at all.
If a server is already running
mecha setup probes http://127.0.0.1:8080 when nothing in the config can
answer — loopback only, one address, and only on an install that is otherwise
stuck. If something is serving there, writing it down is one command:
mecha setup --write
That creates [providers.local] from what the server reports about itself and
makes it the default. Every value comes off /props, which is the only way
context_window reliably ends up being the per-slot figure — -c divided
by -np — rather than the number people write down by hand. It shows you the
lines and asks before writing, and keeps the previous file as config.toml.bak.
If your default provider is hosted and already has a key, nothing is stuck, so
nothing is probed — mecha setup --write says no local server was checked. To
record one anyway, add the table yourself with just its address, then let setup
fill in the rest:
[providers.local]
kind = "local"
base_url = "http://127.0.0.1:8080"
mecha setup --write --provider local
If nothing is running
Let mecha install the server: mecha setup chat (or the first question of
the guided mecha setup) installs llama.cpp, the model recommended for this
machine and the router that serves it — a systemd user service on Linux, a
launchd agent on a Mac. See A local model
above.
Otherwise use a hosted model, which needs an API key that mecha setup will
not write. mecha stores the name of an environment variable rather than a
secret:
[providers.anthropic]
api_key_env = "ANTHROPIC_API_KEY"
Export the variable and start a new shell. Nothing about your key ever reaches a file mecha writes, which is what makes a config safe to copy between machines or commit to a dotfiles repo.
4. Wire in personal context
Everything below is optional and independent — mecha is useful with none of it.
Each is a feature, and every feature is off until it is switched on in
[features]: the install and sign-in commands in the table below do not turn
anything on by themselves. Let mecha setup ask, or switch one on yourself with
mecha features enable <id>; mecha setup lists whichever you have not
answered yet, with the command for each.
And you can say no. At each offer the answer is y, N, or never:
Run `mecha features enable slack`.
run `mecha features enable slack`? [y/N/never] never
noted — `slack` will not be offered again (`mecha setup --undecline slack` undoes it)
N means not today and the question comes back; never records the choice in
~/.mecha/setup-declined.json and the step reads you said no thanks from then
on. That is the difference between a finished install and a permanent defect
list — a declined step is not outstanding, so mecha setup exits 0 and is
usable as your own health check. mecha setup --undecline <step> (or all)
asks again.
Every optional feature whose switch you have not answered can be declined —
mail, documents, Slack, the graph, web search, images, voice, the web app and
the rest. So can the charter, though setup only names it: it is asked
later, or never? and never opens an editor. A switch you wrote false is
already an answer, and mecha features enable <id> is the way back from it.
Everything else is not a preference but something the install needs: a config
file, a provider that can answer, a local server that agrees with its config,
the timezone once a server is wired, and a scheduler once triggers exist. Nor
can you decline anything that is broken rather than merely absent — including
a feature you switched on that does not work yet. "I don't want mail" is a
preference; "stop telling me my mail is broken" is not one a setup tool should
be able to record.
| What it gives you | Switch on | Then | |
|---|---|---|---|
| Mail and calendar | Gmail and Outlook behind one surface. The model names an account, never a provider. | mecha features enable mail | mecha-mail auth (asks Google or Outlook, and a name) |
| Documents | Google Docs, Sheets and Slides under drive.file — only files it created or you handed it in Google's own picker. | mecha features enable docs | mecha-docs auth (the account is --account, default personal) |
| Slack | A remote control: watch a run from a phone, approve sends, pass files both ways. | mecha features enable slack | mecha slack auth |
| Knowledge graph | Memory — who people are, what happened when. A separate project, wired in over MCP. | mecha features enable graph | nothing: enable builds mecha-graph-mcp from its pinned commit if none is on your PATH |
For mail, documents and the graph, mecha features enable also writes the
[[mcp]] entry that runs the server — found on your PATH or in
~/.cargo/bin, so install the program first — with its results marked
untrusted, and stages mail's sends and documents' writes in an [outbox] for
your review when you have none. An entry or [outbox] you wrote is never
edited; enable says what yours lacks. Each feature's page shows the entry:
Mail and calendar,
Documents,
Memory.
Three things worth knowing before you start:
- Mail and calendar sign in with an app you register yourself, once.
mecha does not ship one for Gmail or Outlook: a mail sign-in app published
with an open-source program can be copied by anyone, which turns it into a
phishing kit under mecha's name.
mecha-mail authwalks you through registering your own, opening each page of Google Cloud or Microsoft Entra in turn (about five minutes), then signs you in. Already registered one for another machine? Answer yes when it asks, and give it Google's client file or Outlook's two ids instead (how). Google Docs needs none of this: it signs in with mecha's own Drive app, which can only reach files mecha made or you pick. - Mail and documents come from the
mecha-mailcrate, whichcargo install mecha-cli mecha-mail --lockedinstalls besidemecha:mecha-mail,mecha-docs,mecha-googleandmecha-outlook. - The knowledge graph's own sources — ambient conversations, a calendar
feed, messages — are configured with
mecha-graph source, in that project. mecha reaches the graph only through its MCP tools and deliberately knows nothing else about it, somecha setupnames those sources and never drives them.
Set the timezone once a server is wired
As soon as any MCP server is configured, mecha setup asks for [agent] timezone, and this one cannot be declined: the mail servers resolve today and
tomorrow in that zone and never the machine's, so without it they refuse every
relative window rather than guess the day. It is an edit, not a command — add an
IANA name under [agent] in ~/.mecha/config.toml:
[agent]
timezone = "America/New_York"
Reading mail or the graph marks the conversation as holding third-party content, which is what arms the trifecta interlock. That is the intended behaviour, not a misconfiguration.
5. Write a charter
The one step that is about you rather than about the machine, and the one most people never find:
mecha charter edit
A charter is a short, ranked list of standing priorities in your own words. It rides in every run's prompt, so it is how mecha knows what you actually want from it rather than only what you asked for in this sentence.
[[line]]
id = "tell-the-truth-early"
text = "Tell me the truth early, especially when it disappoints."
[[line]]
id = "protect-my-attention"
text = "Do not put something in front of me that I could not act on today."
Order is rank and there is no priority field: when two lines conflict, the higher one wins outright, and no amount of urgency on a lower line outranks a higher one. Re-ranking is moving a line.
A line may also carry a [line.sensor] table — a kind from a closed set and
a setpoint you wrote, such as kind = "outbox_age" with setpoint = "24h" —
so that runs which touch what the sensor watches are appraised against that
line. The template you are handed shows one commented out;
the charter page
lists the kinds and their units.
mecha charter edit creates a commented template if you have no file yet and
hands it to $EDITOR — the same bytes the TUI's /charter and the web settings
page hand out. mecha never writes a priority. The template is comments only,
there is no generate button anywhere, and no tool a model can call reaches this
file; a model that could edit its own standing priorities could edit its way
around every other guardrail.
One authoring trap worth knowing before you start: a line shaped like "never disappoint anyone" produces sycophancy and withheld bad news. Point it the other way, as the first example above does.
See How appraisal works for what the charter is part of.
6. What is deliberately not set up
Nothing is scheduled for you. A scheduled unattended agent run on a machine
holding your mail is not something to opt anyone into silently — the same
reasoning that keeps [[trigger]] out of a project's mecha.toml, where a
cloned repository would be handing itself a cron slot on your machine.
When you do want one, Triggers covers it, and the runner is a unit you can read before you let it run:
mecha trigger daemon --print-unit > ~/.config/systemd/user/mecha-triggers.service
Next
- First run — start it and use it
- The charter — every rule and surface, in full
- Configuration — every setting, and what derives from what
- Images — if you want it to look at screenshots