Configuration
Lua, and a program rather than a data file: it may probe the machine, loop and branch. Nothing is discovered by scanning — a file the entry point does not name does not load.
The entry point
-- ~/.config/magi/init.lua — the only entry point. -- Nothing is discovered by scanning: a file not named here does not load. magi.load("clients/hexe.lua") magi.load("clients/oslo.lua") magi.load("clients/balthasar.lua") magi.load("tools.lua") magi.model = "openrouter/anthropic/claude-sonnet-4.6" magi.confine = true -- refuse paths outside the session root magi.allow = { … } -- answered in advance, not under pressure
What it takes
| setting | does |
|---|---|
magi.model | which model, as magi models prints it |
magi.confine | whether read, write and edit refuse paths outside the session's directory |
magi.allow | permissions granted in advance, so they are not asked about |
magi.trusted | directories whose .magi.lua is as good as this file |
magi.env | environment every process magi starts is given, on top of what it inherits |
magi.project | what this session is called, in the name other sessions see |
magi.agent_talk | how far one session may reach another |
magi.ui | every colour, glyph and measurement the screen draws with |
magi.melchior · magi.balthasar | settings handed to that sibling, in its vocabulary — one place to edit rather than two |
A project's own file
A .magi.lua arrives with a checkout. Cloning a repository and running magi in
it must not be enough to add a tool — a tool names a command to run — or to widen what runs
without asking.
| a project file may | and may not |
|---|---|
| choose a model the machine already offers | declare a tool |
| set ordinary settings | touch confine, allow or trusted — fatal, not a warning |
| load its own files | name its own directory as trusted |
The one way past it is from your own configuration: naming a directory in
magi.trusted makes its project file as good as yours. A decision made once, in
advance, in the file only you can edit. Without a way to say yes, the rule would be worked
around instead of used.
Configuring a sibling through magi
magi asks each sibling what it takes, hands over what your config named, and reports anything the far side would not accept — a coordinator and a sibling disagreeing about what a name means is worth a line on stderr.
magi.balthasar = { promote_floor = 0.6 }
magi.melchior = { max_tokens = 8192 }
$ balthasar needs # what it will accept, in its own words
$ melchior needs