moa

Open-source coding agent · self-hosted

moa works on your machine. You steer it from anywhere.

It runs next to your repos, your toolchain and your dev servers, and its sessions live there too, not in a browser tab. Start one at your desk, then follow it, answer it or change its course from your phone.

MIT · one Go binary · Linux and macOS

moa on a desktop: the session 'Retry flaky tide fetches' is running; go vet and go test pass on four packages, and the sidebar shows one session waiting for an answer and another with an unread result. The same session on a phone, still running, with a Stop button and a composer to steer it.
The same session, at the desk and on the phone.

Why moa exists

“I did not build moa to replace my computer. I built it because I could not always be at one.”

At some point my life stopped giving me long stretches at a desk. Some days I had two hours at the computer; some days, one. I tried the existing answers — remote-control apps for coding agents got me halfway, but sooner or later something always forced me back to the physical machine: a stuck process, an environment to bring up, a result I could not see from my phone.

So I built moa. The agent lives on the machine where my code, repositories, and tools already are, and I steer it from wherever I am.

As I write this, I have not opened my laptop in three weeks, and I am putting in full days of real development work.

— from moa’s README, written on a phone

What it does

It works on the machine. You decide from wherever you are.

It changes the code in your repo.

moa reads, plans, edits and runs your tests until they pass. Every change is a diff you can open.

A diff of internal/retry/backoff.go inside moa: a MaxDelay field, a RetryAfter interface and a Permanent error type added.

You answer from your phone.

In ask mode it stops before a command and shows what it wants to run. Allow it once, always, or not at all.

A permission request on a phone: npm install -D vite@^6.0.0 vitest@^3.0.0 in ~/src/ledgerly, with Allow once, Always for Bash(npm:*) and Deny.

You point at the problem.

Open your running app inside the session, tap the wrong element and say what is off.

Live Preview on a phone: an invoice amount is picked and a note says amounts ignore the invoice currency.

It splits the job.

Subagents take parts of the work in parallel, each on the model you pick. Open any of them to watch it.

An audit session running three subagents in parallel: currency formatting, unused exports and a review of InvoiceList.ts.

Several at once, one screen.

Keep sessions side by side at your desk, each in its own pane, working until it is done or needs you.

Four sessions in a grid: two tidepool sessions running, a ledgerly audit waiting on three subagents, and a finished one with its summary.

Project owners

Give the project an owner. Keep seven features moving.

The owner runs each feature in its own session, knows the project the way you do, and comes to you only with what it cannot decide alone.

The tidepool owner in moa: seven feature sessions under it, four running, two waiting on you and one stopped with an error; the owner brings one decision, citing the project's book, with its recommendation. The same owner on a phone, its face in the header, the seven sessions below its question.

One session per feature.

Each feature gets its own session, working on its part. The owner's row tells you how many are working and which ones are waiting on you.

The owners on a phone, each with its face: tidepool says 4 working and 3 waiting on you.

It knows what you know.

Decisions, features and the people who ask for them live in the project's book. The owner checks it before it asks you, and writes down what you answer.

The tidepool book in moa: PROJECT.md, OWNER.md, a glossary, people.md and the project's areas.

It asks less as it learns.

Once it knows the project, or the feature, it goes ahead on its own and tells you what it did.

How owners work

Models

Use the plan you already pay for.

moa talks to each provider straight from your machine. Sign in with your subscription or use an API key. Pick the model per session, and give a subagent a different one when the job calls for it.

ProviderSign in withCommand
Anthropic Claude Claude Pro or Max, or an API key moa --login anthropic
OpenAI GPT ChatGPT Plus or Pro, or an API key moa --login openai
xAI Grok SuperGrok, or an API key moa --login xai
Meta Muse Muse, or an API key moa --login meta

There is no moa account and no moa server in between. You pay your provider, and nobody else.

Also in the binary

The rest of the kit.

Where it runs

Your machine, your boundary.

Stays on your machine

  • Repositories, dependencies and credentials
  • Session history and project memory
  • Running processes, containers and dev servers
  • Who can reach it: localhost, Tailscale or your own proxy

Goes to your provider

  • Your prompts and the code the model needs to see
  • Tool results that matter to the task

Before you open a port

moa serve listens on localhost and has no authentication by default. Anyone who reaches an open port can drive its agents. Keep it on localhost or a private network, set a token, and read the security notes first.

Let moa run.

One binary for Linux and macOS. Install it on the machine where your code lives, sign in to a provider, and open the web UI.

# install
$ curl -fsSL https://letmoa.run/install.sh | sh
# sign in: anthropic, openai, xai or meta
$ moa --login anthropic
# start it where your repo is, then open http://127.0.0.1:8080
$ moa serve

Or brew install e-aleixandre/tap/moa, or grab an archive from Releases. Open source, MIT, v0.42.