Skip to main content

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:

  1. 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, with ANTHROPIC_API_KEY set in your shell). The local model installs on Linux as a systemd user service and on a Mac as a launchd agent.
  2. Each optional feature, one at a time: what it does, what it downloads, and y, N or never. A feature that needs another says so.
  3. One summary and one Start?: everything you said yes to and the total download. Nothing is fetched or switched on before that yes.
  4. 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 next mecha setup.
  5. 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 youSwitch onThen
Mail and calendarGmail and Outlook behind one surface. The model names an account, never a provider.mecha features enable mailmecha-mail auth (asks Google or Outlook, and a name)
DocumentsGoogle Docs, Sheets and Slides under drive.file — only files it created or you handed it in Google's own picker.mecha features enable docsmecha-docs auth (the account is --account, default personal)
SlackA remote control: watch a run from a phone, approve sends, pass files both ways.mecha features enable slackmecha slack auth
Knowledge graphMemory — who people are, what happened when. A separate project, wired in over MCP.mecha features enable graphnothing: 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 auth walks 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-mail crate, which cargo install mecha-cli mecha-mail --locked installs beside mecha: mecha-mail, mecha-docs, mecha-google and mecha-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, so mecha setup names 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​