Getting started with metor
In metor, agents become persistent bots. A Bot is a named agent instance with its own role, history and files. A Space is the shared environment where your bots live and run.
This guide walks through the web interface. It assumes a running installation (see
INSTALL.md for servers or the quickstart in the README for a local
box) and that you can open the interface - locally at http://127.0.0.1:6010/bots/, on a server
at https://<your-domain>/bots/ after opening your setup link (section 1).
1. Sign in and devices
The interface has no passwords. The first browser gets in with a setup link that the installer
prints at the end (and that metor auth link inside the box prints again at any time, valid for
24 hours, single use). Every further phone or browser is linked from a device that is already
signed in: open the ⋮ menu at the top of the bot list → Manage Space, section My devices & notifications, click Link a device, and on the new
device either scan the QR code with the camera or open the interface and type the pairing code on
the sign-in page. Links and codes are valid for two minutes.
The My devices & notifications tab also lists every signed-in browser (name, last seen) - remove one to sign it out, or
sign out the device you are on. Lost all devices? metor auth link over SSH mints a new setup link.
Manage Space → Connectors lists MCP servers every bot can use: Add → From the directory offers well-known ones (a shared memory, documentation lookups, DeepWiki, GitHub, search APIs) and pre-fills the form, Custom connector takes any server by command or URL with its environment variables or headers. Bots use a connector on their own, like the browser; switch on Ask before each use to get an approval card for every call instead. Keys and tokens are stored inside the Space. A connector reaches a bot when the bot starts - after a change, the button Restart running bots does that for you. Under App settings, Appearance (text size; a compact bot list with one line per bot; whether the Claude quota bar shows always, never or only from a chosen usage) and Behaviour (sort the bot list by latest activity, newest chat on top like a messenger; which view a bot opens with on a wide screen) are remembered per device.
On the phone or tablet the interface installs as an app. Android: the browser’s menu or Manage Space → My devices & notifications → Install metor as an app. iPhone and iPad: Share → Add to Home Screen, open metor from the home screen and sign in there once with a pairing code (the home-screen app has its own cookie jar). Then turn on Manage Space → My devices & notifications → Notifications on this device: you get a push when a bot needs an approval, has finished a reply or stopped unexpectedly - never on the device that is looking at that chat. The box sends these itself, no third-party service is involved; the interface must be reached over HTTPS for this.
2. Create your first bot
Click the round + at the top right of the bot list.
- Name - free text, for example
ScoutorFußball-Späher 2. The dialog shows the id it derives from the name (fussball-spaeher-2: lower case, umlauts asae/oe/ue, everything else a hyphen) - that id is the directory name, part of every link and the address other bots use; change it there if you want a different one. The name is what you see everywhere else. - Role - what this bot is for. A good role is one or two sentences about the job and the way of working, not a task list: “Researches topics on the web and writes short, sourced summaries as Markdown files. Asks before spending more than an hour on something.” The role becomes the top of the bot’s standing instructions; concrete tasks come later in the chat.
- Runtime and Model - the harness that runs the bot and the model it uses. Claude Code offers Opus, Sonnet (default) and Haiku; Codex offers the current GPT models. Both can be mixed freely across bots; a bot’s runtime and model cannot be changed in the interface afterwards (create a new bot instead).
- If the chosen runtime is not set up yet, the dialog shows an amber box with a Sign in button. Claude Code: open the link, sign in with your subscription, then paste the code the page shows at the end into the box and confirm. Codex: you get a link and a one-time code, open the link, enter the code, confirm - the box waits and turns green when the login has arrived. Links and codes are valid for 15 minutes. Runtime logins are per box, not per bot.
Create sets up the desktop and the session; that takes up to a minute. The bot appears in the sidebar like a chat in a messenger: its picture, the time of the last message, a one-line preview of it and, once the bot has written something you have not looked at yet, a badge with the count. The second line is what the bot is up to: three pulsing dots while it starts, thinks or writes, “waiting for your approval” while an approval card is open, the error in red when it stopped with one, otherwise the last message. A stopped bot is greyed out in the list and stays selectable; the header then shows a Start button.
3. Chat
Select the bot and type a message into the box at the bottom. Enter sends, Shift+Enter adds a line break.
- Streaming: the answer types in live in a “typing” bubble and settles into a normal message when the turn is complete. Markdown is rendered.
- Tool lines: grey lines with a gear icon show what the bot is doing (reading a file, running a command, opening a page). Click a line to expand the full command and its result; click again to collapse it.
- Approval cards: when a connector marked Ask before each use (Manage Space → Connectors) is called, an amber card titled “Approval” appears with the tool, the reason and the exact input. Choose Allow or Deny. The card stays in the history with the decision. While a card is open the bot list says “waiting for your approval”, and with notifications turned on (Manage Space → My devices & notifications) your phone gets a push. Be clear about what asks and what does not: inside the Space nothing asks - not the shell, not the browser, not the files. A bot that is signed in to a site in its browser can act there without a card. Approval cards exist for connectors marked “Ask before each use”, and today only Claude Code bots show them; Codex, Gemini and Copilot bots run every connector without asking (ADR-0019 is the plan to close that gap). Give a bot accounts it may use freely, and keep the sensitive ones behind an asking connector.
- Stop: while the bot is working, a red stop button sits in the header. It interrupts the current turn; the bot keeps its context and you can send the next message right away.
- Message status: your own messages carry ticks like in a messenger - one tick while the message is on its way, two grey ticks once the bot’s session has taken it, two green ticks once the bot has answered; “failed” with an error line when the bot is not running.
Messages triggered by a routine (see below) appear in the history as grey bubbles marked “Routine”.
4. Attachments
You can hand files to the bot in three ways: the paperclip button next to the input opens a file dialog; paste (Cmd/Ctrl+V) drops a screenshot or a file from the clipboard; drag and drop anywhere onto the chat works too. Every attachment shows as a chip above the input with a thumbnail (images) or a file icon, the size, and a small x to remove it again. Limits: 25 MB per file, 10 files per message. Pasted screenshots get a numbered name.
On send, the files are stored under uploads/ in the bot’s directory and the bot receives one
[Attachment: ...] line per file with the full path. It reads images itself with its own tools,
so attachments work the same for every runtime. In the history your attachments appear as
thumbnails or file chips inside your message; click to open them.
5. Files from the bot
Whenever the bot mentions a file it created - a report, an export, a screenshot - the chat offers
it as a file card inside the bot’s message: images show a preview, other files a name, size and
download. Bots do this deliberately with a [File: path] marker in their reply, and file paths
mentioned in plain text are picked up automatically as well. To browse everything the bot has,
open the Files tab in the computer panel (next section).
6. The computer panel
The computer button in the header (a small monitor) shows the bot’s computer next to the chat; drag the divider between the two to give either more room (the share is remembered per device). On a phone the computer replaces the chat while it is shown. The computer panel has three sub-tabs:
- Screen - the bot’s desktop, streamed via noVNC. You see the browser window the bot drives and can take over with mouse and keyboard at any time: log into a site, solve a captcha, approve a two-factor prompt, close a pop-up. Logins persist in the bot’s browser profile, so one manual login usually lasts. When a bot gets stuck it says so in the chat and waits for you. Right after creating a bot the panel may show “Loading the bot’s computer” or “Waiting for the bot’s computer” for a few seconds until the desktop is up.
- Terminal - a real shell in the bot’s directory (copy and paste supported). Use it to look around, run a command yourself, or fix something the bot could not. The shell lives as long as the tab is open; a page reload starts a fresh one.
- Files - a file browser rooted at the bot’s directory: click folders to descend, use the breadcrumb to go back up, click a file to open or download it. Hidden (dot) directories are not shown.
7. Routines
A routine is a recurring task the bot runs on its own. You do not fill in a form - you tell the bot
in the chat: “Every weekday at 7:00, check the three feeds in sources.md and post a five-line
digest.” The bot creates the schedule itself and confirms it. Times are in the box’s local time zone
(Europe/Berlin by default, see INSTALL.md).
The routines button in the header (a calendar with a clock) shows the bot’s routines next to the chat, one card each in plain words: when it runs (“Weekdays at 07:00”), the next and the last run, whether it is active or paused and why, and the task the bot receives. Below the cards the recent runs are listed. Every card has Pause / Resume and Run now - they work without the bot, so a routine can be switched back on even when the bot’s quota is used up. Changing a routine works the same way it was created: ask the bot to move the time, change the task, or delete it. Each run arrives in the chat as a grey “Routine” message followed by the bot’s work.
Auto-pause: a routine that has run 20 times without you sending the bot any message is paused
automatically and marked “paused” in the panel; the bot leaves a note in the chat. Resume it in
the panel or tell the bot. The threshold is configurable per installation (METOR_ROUTINE_GUARD,
0 disables the guard). A run that was missed while the box was down is caught up once after the
restart. A schedule that never matches a date (the 31st of February) is refused when the routine
is created; one that runs out of dates pauses with a note.
8. Runtimes and models
Each bot runs on one runtime - Claude Code, Codex, Gemini CLI or GitHub Copilot - and one model, chosen at creation. The header of a bot shows both as a small badge on desktop widths.
- Claude Code bots use your Claude subscription. The sidebar shows the subscription’s quota (“Claude quota”, five-hour window and, where available, the weekly window) as a bar; all Claude bots share it. When it is exhausted, Claude bots wait until the window resets.
- Codex bots use your ChatGPT subscription. Their quota is separate and not shown in the interface yet. Codex bots can chat, use shell and files, drive their browser, run routines and send files; assigning tasks to other bots is not available for Codex bots yet.
- Gemini CLI bots use a Gemini API key from Google AI Studio - the free tier (about 1,000 requests a day) needs no subscription. Sign in once from the create dialog: get the key at AI Studio, paste it, done; it stays inside the Space. Gemini bots can chat, use shell and files, drive their browser, run routines and send files; like Codex bots they cannot assign tasks to other bots yet. The model choice is “Auto” - Gemini picks the model per task and the bot’s header shows which one answered last - or one of the models Gemini lists, or a pinned id through Other model id….
- GitHub Copilot bots use your GitHub Copilot subscription - any plan, Free included - and with it models from every vendor (Claude, GPT, Gemini, Grok, Kimi). Sign in once from the create dialog with GitHub’s device code; the login stays inside the Space. The model choice is “Auto” - Copilot picks per task and the bot’s header shows which model answered - or one of the models Copilot lists. Copilot bots chat, use shell and files, drive their browser, run routines and send files; like Codex and Gemini bots they cannot assign tasks to other bots yet. If a Copilot bot answers “Access denied by policy settings”, your Copilot settings (or, in an organisation, its admin) have to allow Copilot CLI and MCP servers.
Which models? For Claude Code the choice is a family - Fable, Opus, Sonnet, Haiku - and each name always means the newest model of that family that Claude Code offers, so the list keeps up with Claude Code itself. The version shown next to the name (“Fable 5.1”) comes from what Claude Code reports and, as soon as a bot of that family has answered, from the model that actually ran - that one counts, because Claude Code’s own list can lag behind. For Codex the interface shows the models Codex offers right now; it asks Codex each time the create dialog opens (cached for ten minutes). Once a bot of a family has answered, the dialog also shows the real id behind the name (“Right now that is claude-fable-5-1”). The last entry, Other model id…, pins a bot to a full id
- it comes prefilled with that one - or takes any id the runtime knows, for a model the list has
no name for yet; on the command line that is
metor bot create --model <id>. A pinned bot stays on that model when a newer one appears; a bot on a name follows.
Runtime logins live in the box (one per runtime, shared by all bots of that runtime) and survive restarts and updates. If a runtime’s login expires, only that runtime’s bots stop.
9. Mobile
On a phone the interface follows the messenger pattern: the sidebar is the bot list, tapping a bot opens its view, the back arrow at the top left (or the browser’s back gesture) returns to the list. The computer button in the header switches between the chat and the computer. Routines and the bot actions (Pause, Start, Remove) are in the more menu (the three dots). The screen tab works with touch, but for real intervention a desktop browser is more comfortable.
10. The desktop app
metor is also an app for macOS, Windows and Linux (client/desktop, built from the repository or
taken from a release). It shows the same interface, and adds what a browser tab cannot:
notifications for approvals, finished replies and unexpected stops while the app runs, a tray
icon, several Spaces side by side (menu Spaces - the one you are looking at is
ticked there, and the app opens with it again next time), and screen sharing for the bots.
On first start the app asks one question: should the Space be on this Mac or on a
server? On this Mac, the app creates it right there (see below). On a server, paste the setup
link (from the installer or metor auth link inside the box - the address comes with it), or
enter the address plus a pairing code from Manage Space → My devices & notifications → Link a device on a device
that is already signed in. The app then appears under Devices as “metor app on Mac/Windows/Linux”;
removing it there signs the app out, and the app’s connect screen offers the Space again.
The Space on your own Mac. You do not need a server: choose On this Mac and the
app does what the situation needs - no computer yet, it sets one up (the first time this
downloads the image, about 1 GB, a few minutes; the output shows live); one that is stopped, it
starts; one that is running, it opens; several, it lets you pick. It needs a container runtime -
Apple’s container on an Apple silicon Mac with macOS 26 (install it from Apple’s GitHub
releases), otherwise Docker or Colima - and says so with links when none is installed. After
that the app starts the Space whenever it opens (menu Spaces → Space on
this Mac to switch that off, or to start and stop by hand), so a reboot of the Mac changes
nothing. That computer has its own volumes: sign in to a runtime once under New Bot →
Sign in, then create bots as usual. A Space that does not answer - stopped, or a server
that is down - lands on the connect screen with the reason and a Try again button instead of a
dead interface.
A Space is the shared environment where your bots live and run. It can run on your Mac or a server. The computer panel shows an individual bot’s desktop, terminal and files.
11. Managing bots
Every bot has a picture - in the list and in the header. When you create a bot, the dialog fills in one to three initials from the name as you type and picks a colour; keep them, change the letters, pick another colour, or upload an image of yours (PNG, JPEG, WebP or GIF, up to 2 MB). Later, a click on the picture in the bot’s header opens the same choices.
With a bot selected, the header (or the more menu on phones) offers:
- Pause - stops the bot’s runtime session and desktop. The bot keeps everything: directory, history, routines, session context. Routines do not fire while a bot is paused.
- Start - starts a paused or stopped bot again; the session resumes with its context.
- Remove - after a confirmation, stops the bot and deletes its directory, including the
chat history, uploads, files it created and its routines. This cannot be undone; download what
you need first. (The command line offers
metor bot rm <name> --keep-filesto remove the bot but keep the directory.)
Bots restart automatically when the box restarts, unless they were paused.
12. Troubleshooting
- A bot shows “stopped” and messages fail. Most often the runtime login has expired. Sign in
again: open “New Bot”, pick the runtime and click Sign in (terminal alternative for Claude
Code:
docker compose exec --user box -e HOME=/home/box box /home/box/.local/bin/claude auth login, ordocker exec --user box -e HOME=/home/box -it metor-box /home/box/.local/bin/claude auth loginon a local box). Then press Start on the bot. The box’s supervisor log (docker compose logs box) shows the reason if it was something else. - The screen says “connecting” or “Waiting for the bot’s computer” for a long time. Reload the page. Right after creation the desktop needs a few seconds; after a box restart the desktops come up one by one. If it never connects behind your own reverse proxy, check that the WebSocket paths pass through as described in INSTALL.md.
- The bot does not answer and the sidebar quota bar is full. The Claude quota for the current window is used up (the bar turns red above 80 percent); all Claude bots share it. Wait for the window to reset or use a Codex bot in the meantime.
- A routine stopped running. Open the routines panel: if it is marked “paused”, the auto-pause kicked in - ask the bot to resume it.
- An attachment is rejected. Check the limits (25 MB per file, 10 per message).
- A bot is stuck in the browser (login, two-factor, captcha). Open the Screen tab, do the step yourself, then tell the bot in the chat to continue.
Screen size in the split view
Under App settings → Behaviour → Adapt screen resolution to panel, you can turn automatic resizing on or off for this device (on by default). Off keeps the current resolution and scales the view to fit the panel.
The embedded Screen adjusts its resolution to the available panel space after you finish dragging the divider. A narrow panel gives the browser a portrait layout rather than shrinking a wide desktop. Browser tabs and the current page stay open. While a bot is working, the existing screen is scaled; the resolution adjusts once the bot is idle. If several devices watch the same bot, they share its screen resolution.
This requires the updated Space image with TigerVNC. Existing Spaces must update their image and restart before this feature is available; updating only the desktop app is not enough.
Paste text into the bot’s browser
Click the destination field on the bot’s Screen, then press Cmd+V on a Mac or Ctrl+V on Windows/Linux. You can also use Paste at the top right of the Screen. If clipboard access is unavailable, Paste opens a text field: paste there and choose Paste into screen. The transfer supports plain text, including Unicode and multiple lines, up to 256 KB. It pastes into the currently focused remote field and does not submit the form. Images and files still go through chat attachments. This requires the updated Space image.
Start the local development version on macOS
From a repository checkout, double-click these scripts in Finder, or run them in Terminal:
scripts/build.commandbuilds only changed components. It installs dependencies when their package files change, builds the UI once, and skips the entire image build/export when the backend is unchanged. Run it after code changes; it does not restart the Space.scripts/run.commanduses the saved build and opens the desktop app. It keeps a running Space when its image digest matches, and transfers changed UI files without restarting bots. A new backend image recreates the Space with its existing data volumes.
For ordinary launches, use only run.command. The development desktop app itself is
reopened so that UI and Electron changes are visible. Changes to source files take effect
after build.command; launching does not build automatically.
Optional overrides from Terminal:
./scripts/build.command --force # rebuild despite the local fingerprints; image layer cache still applies
./scripts/run.command --restart # restart even with the same image, e.g. after changing Space configuration
Saved bots, chats and runtime sign-ins stay in their volumes. Applying a new backend image
or requesting a restart interrupts running bot turns; UI-only updates do not. Cached build
fingerprints live in the ignored .metor-dev/ directory and are written only after each
successful step. The first build initializes this cache. Missing or replaced images are
rebuilt even if the source files are unchanged. --force reruns the UI and image builders but retains their layer caches; it does not
force dependency updates. The local source cache does not poll upstream.
The default runtime is Apple’s container and the image is metor-box:resize-test;
METOR_RUNTIME and METOR_BOX_IMAGE can override these. Node.js/npm and the runtime must
already be installed. Docker identity handling is supported; the live local workflow is
verified with Apple’s runtime on macOS.
Automatic runtime sleep
After five minutes without work, a bot releases its runtime processes. Its status shows Sleeping; messages, routines and slash commands wake it automatically. The next response may take a little longer while the runtime resumes its session. Browser tabs and the desktop stay open. Running turns, pending approvals and reported background tasks prevent sleep.
Set METOR_RUNTIME_IDLE_SECONDS for the Space to change the delay; 0 disables
sleep. For the local development Space, for example:
METOR_RUNTIME_IDLE_SECONDS=600 ./scripts/run.command --restart
Keep the variable in your launch environment for subsequent recreations; Compose
reads it from its .env. This setting is not a per-device UI preference.
Copy text from the bot’s browser
Select text in the bot’s browser, then click Copy at the top right of the Screen. You can now paste it on your computer. If clipboard permission is unavailable, a dialog shows the selected text: press Cmd+C or Ctrl+C, then close it. This reads the Linux desktop’s text selection only when you click Copy; it does not synchronize in the background. Plain text up to 256 KB is supported. Rebuild and restart the Space to enable it.
Desktop clipboard synchronization
Under App settings → Behaviour → Sync clipboard with active screen (on by default), the desktop app transfers newly copied plain text from the focused bot Screen to your local clipboard. Selecting text alone does not trigger a transfer. Use Cmd+C / Ctrl+C in the bot browser and paste locally; Cmd+V / Ctrl+V on the Screen sends local text to the bot. Switching away pauses synchronization. Existing remote clipboard contents are not imported when entering a Screen. Text is limited to 256 KB.
Copy/Paste buttons hide once synchronization is available. Disable the setting to use them again; web clients and older Spaces retain the buttons. Rebuild and restart both the Space and desktop app after updating the checkout.
Diagnose sleep, routines and runtime errors
Open a bot’s ⋮ → Event log. The view refreshes every five seconds without waking its runtime. Filter by routines, runtime activity or errors/interruptions. Click a run ID to follow one routine from queuing through waking and processing to its outcome. Export downloads all matching retained records as JSONL, including records beyond the first page. Times display in your local timezone; exports use UTC.
Events live in the bot’s .metor/events.jsonl and events.jsonl.1, up to 2 MiB each.
Older records expire on rotation; export them before they expire when investigating
an issue. Records begin with this version; earlier history is not reconstructed.
Routine run IDs also appear in .metor/runs.jsonl. A queued routine is not yet a
completed turn. Completion means the runtime finished its turn, not that metor has
independently verified the task’s result. A process crash marks active work interrupted
when its host detects the exit or restarts; it does not silently report success.
The event log contains diagnostic metadata, not prompts, replies or tool output.
Detailed runtime error messages remain in .metor/host.log; use
metor bot logs <name> to see its last 50 lines. If writing diagnostic events fails,
the host/Space log reports it and the bot continues. The event log is a diagnostic
history, not an audit log protected against modification by the bot.
RAM protection
Space menu → Manage Space… → Resources & updates → RAM protection shows current available RAM, total capacity and waiting bots. Readings refresh every three seconds. Container limits and estimated reclaimable file cache are included; swap is not counted as available RAM.
A runtime starts only when at least 512 MiB plus the Space reserve is available. The reserve is 10% of capacity, bounded between 256 MiB and 1 GiB. Starts queue in arrival order and run one at a time, with a short settling period. Waiting messages and routines stay in the inbox and start automatically when RAM becomes available. The bot list/chat explain the delay, and the Event log records waiting and admission. If memory cannot be measured, new starts wait until readings recover.
To free RAM, pause a bot you are not using; idle runtimes also sleep automatically. Their browser and desktop stay open while sleeping. Pausing a waiting bot removes it from the startup queue but retains its undelivered messages for a later Start. The guard does not interrupt ongoing work or change the Space’s RAM allocation. Browser, desktop and terminal starts use the same queue. Later growth of already running processes is not limited, so available RAM can still fall while bots work.
App and Space settings
App settings contains appearance and behaviour preferences for this device. The Space menu offers Manage Space, followed by Remove from my overview in native apps. Removing a connection affects this device only and does not stop or remove the Space or its bots.
Manage Space opens inside the app/browser and contains:
- General: change the Space name for all connected devices. The name is stored on the Space and live connections receive updates automatically.
- My devices & notifications: link or sign out your devices and configure notifications for the current device.
- Resources & updates: RAM protection, versions and update information.
- Connectors: MCP servers available to bots.
A Space is personal. Each device has its own revocable session; all signed-in devices can manage the Space. There are no membership roles or invitations for other people. The gateway requires sign-in for protected API requests, including name changes.
Change the RAM allocation
On the desktop app running the local Space, open Manage Space → Resources & updates → RAM for this Space. This shows the actual allocation, total host RAM, a host reserve and the maximum allowed allocation after accounting for other running containers. Choose New total RAM (GiB) in steps of 0.25 GiB. The value replaces the current allocation; it is not added to it. For example, changing from 4 to 6 GiB adds 2 GiB.
For Apple’s container runtime, Apply and restart asks for confirmation because it interrupts running bot tasks. The existing image, data volumes, files, chats and device sign-ins are retained. If the new configuration fails to start, metor attempts to restore the previous allocation. The operation does not rebuild or update the image.
The limit is saved on the host per runtime and container name. Normal starts and updates
reuse it. Precedence is explicit METOR_MEMORY, then the saved allocation, then the
runtime default (4 GiB for Apple; no imposed limit for Docker). When METOR_MEMORY is
set, remove the override and restart the desktop app before changing RAM here.
Apple containers also support reductions down to 1 GiB through Apply and restart. The confirmation warns when current usage exceeds the new limit or cannot be checked. Docker on Linux can increase an existing configured limit live; Docker Desktop VM sizing and remote server changes are not offered here. This setting changes a container limit, not physical RAM or a VPS plan. Custom Apple container configurations that cannot be safely recreated show an explanation instead of Apply.
Waiting for a browser or desktop
Browser, Screen and Terminal requests check RAM before starting missing components. They share the runtime startup queue and the Space reserve. Startup budgets are 512 MiB for a browser, 640 MiB for a full desktop, 128 MiB for the desktop additions when its browser is already running, and 64 MiB for the terminal service.
When a start cannot proceed, the Screen shows Waiting for RAM and retries automatically. The bot list and Manage Space show pending components. The supervisor also retries persisted requests, including requests made by the bot’s browser tool. The browser tool waits up to a minute; if it reports waiting, the requested browser still starts automatically when admitted and the bot can retry its tool call.
Stop cancels queued computer starts. Existing open browsers are reused without another admission check. Event log entries record waiting, admission and cancellation. The guard does not evict browsers or prevent later memory growth in running processes.
Build and transfer the macOS app
On the development Mac, open scripts/build-macos-app.command. It reuses the normal build cache,
packages an arm64 desktop app and exports the built container image. The completed folder is
.metor-dev/macos-app/metor-macos-arm64; transfer that entire folder to the receiving Mac, for example via AirDrop or USB.
On an Apple silicon Mac with macOS 26 or newer, install Apple’s container runtime if needed,
open the included install.command; it quits metor automatically. No Git, Node.js or npm is needed there.
The installer checks the archives, replaces the app in /Applications, imports the image and
opens local Space setup. Updating an existing Apple-container Space requires confirmation and
retains its named volumes. A configured Docker Space is not switched automatically.
The image contains application code, not personal bot data or login volumes. The source Mac’s
uncommitted code changes are included. Runtime boot components and provider access can still
require internet. The app is locally signed for testing, not notarized for public distribution;
for personal tests, the installer removes the quarantine attribute only from the extracted
metor.app. Use it only for your own trusted build. System-wide Gatekeeper settings remain
unchanged; macOS may still require approval to open install.command itself.
This page is metor-com/metor/blob/main/docs/getting-started.md in the metor repository, rendered as it is.