# Arbor: one daemon behind a desktop app, a web UI, a CLI and an MCP server

> Arbor is a native Rust application for running coding agents against real worktrees, and its architectural bet is that everything, the desktop app, the browser interface, the command line and the model context protocol server, talks to the same long-lived daemon. That is what makes remote outposts over SSH and sessions that survive a restart possible.

**penso/arbor** — Run agentic coding workflows in a fully native desktop app for Git worktrees, terminals, and diffs.

- Repository: https://github.com/penso/arbor
- Website: https://penso.github.io/arbor/
- Stars: 837 · Forks: 40
- Language: Rust
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/penso-arbor

## One daemon, four front ends

Arbor is described as a fully native app for agentic coding, built with Rust and the GPUI toolkit, and it gives you one place to manage repositories, issue-driven worktrees, embedded terminals, managed processes, diffs, pull request context, coding agent activity, and a shared daemon.

The daemon is the point. The stated advantage is one daemon-backed model for the desktop app, the web UI, the command line and the MCP server, and the second stated advantage is that the whole thing is built for parallel coding sessions across local repositories, issue queues and remote outposts.

That design explains a set of features that would otherwise look scattered. Sessions are persistent and daemon-based, so they survive application restarts. The remote support is not a separate product but a mode of the same daemon, reached over SSH or Mosh. The MCP server is not a wrapper around the desktop app but a client of the daemon's API, which is why an agent can create a worktree or read a diff without a screen.

The crates table in the README shows the decomposition. There is a core crate for the worktree primitives, change detection and agent hooks, a daemon crate that serves the remote HTTP API and the bundled web interface, a client crate with the typed client and the shared API data transfer objects, a desktop crate for the GPUI application, a command line crate, an MCP crate, and separate crates for the SSH and Mosh transports, the terminal engine glue, an optional workflow orchestration runtime called Symphony, and a benchmarks crate.

The project is MIT licensed, the home page is a GitHub Pages site, and the last push was on 2026-09-21 with the most recent releases dated in March 2026, which tells you the release naming is a date and a sequence rather than a semantic version.

## Worktrees, issues, and a naming rule you control

The first capability group is about the worktrees, which are the unit of work in a parallel agent workflow.

You can list, create and delete worktrees across several repositories, and you can create managed worktrees directly from GitHub or GitLab issues, so a queue of tickets becomes a queue of isolated checkouts. Before anything is created, the application previews the sanitised worktree name, the branch name and the target path, which matters because those names end up on disk and in a branch list.

The naming is configurable per repository, with a branch rule in the configuration file using a bracket token, so a worktree branch can follow a convention your team already uses rather than one the tool invented. Deletion asks for confirmation and detects unpushed commits, and there is an optional cleanup of the branch when the worktree goes away, which is the difference between a tidy repository and a list of stale branches.

There is also a small set of conveniences that show the tool has been used in anger: navigation history for moving back and forward between worktrees, the timestamp of the last git activity in each one, and automatic linking of an issue to an existing branch or an open pull request or merge request, so an agent that already started work on a ticket is connected to it.

The configuration file is a TOML document, and it also holds the task definitions and the provider configuration, which is worth noting because a tool that keeps its state in one editable file is far easier to script against than one that hides it in a database.

## The terminal is a real PTY, and the agents are attached to it

The embedded terminal group is where the fidelity claims live.

It is a built-in pseudo-terminal with truecolor and the 256 colour mode, and there is an experimental embedded engine from a separate terminal implementation, used by default when it is available, behind a compile-time feature flag. That is a sensible way to try a new engine, since the flag means the old path is still there and the choice is made at build time rather than at runtime.

The sessions are persistent and daemon-based, so they survive an application restart, and you can attach and detach from them and send signals including interrupt, terminate and kill. Managed processes come from two places, a Procfile and the configuration file, and the tool keeps restart state, memory metrics and a link between a process and the terminal session it belongs to.

Scheduled tasks are configured in the configuration file as task entries, and they can carry optional triggers for a coding agent, which is the mechanism that lets a scheduled job hand work to Claude or Codex. The terminal also watches for the bell character and fires completion notifications, so a long build that finishes in a background tab still tells you.

The repository contains a Procfile at its root, which tells you the project expects a process-oriented workflow of its own, and the configuration file is documented with hot reload, so editing a task definition does not need a restart.

## Agent chat, and visibility into agents you did not start there

Two separate features concern coding agents, and they are worth distinguishing.

The first is the agent chat. You can have interactive chat sessions with agents that speak the agent communication protocol, and the README names Claude, Codex, Pi and Gemini, with more available through a bridge for that protocol. On the other side there is support for OpenAI-compatible providers, specifically Ollama, LM Studio, OpenRouter, OpenAI, and in fact any endpoint that speaks the chat completions path. Responses stream, using server-sent events for the OpenAI-compatible providers and a line-delimited JSON format for the protocol agents. The model list is discovered automatically by probing the models endpoint of each configured provider at startup, and a selector groups the models by provider with distinct icons for the two kinds. Provider settings live in the configuration file under provider sections, sessions persist across daemon restarts, and token usage is tracked and displayed.

The second feature is visibility. The application detects running coding agents, specifically Claude Code, Codex and OpenCode, and shows working or waiting state with colour coded dots, updated in real time over a websocket in both the desktop and the web interface. There is also compatibility with older session formats and targeted clear events, which is the kind of detail that only appears when long-lived daemon sessions have to survive protocol changes.

The difference matters in practice. The chat is a place where you ask an agent to do something. The visibility is a place where you find out that an agent is running, in a terminal you did not open, and is waiting for you.

## Remote outposts over SSH and Mosh

The remote section is the most distinctive thing in the project, and it is built out of the same daemon rather than a separate implementation.

Three companion binaries ship with the desktop application. The HTTP daemon serves the remote API and the bundled web interface. The command line exposes daemon-backed commands for health, repositories, worktrees, terminals, processes and tasks. And the MCP server exposes Arbor over standard input and output with structured tools for the same set of resources, plus resources for daemon snapshots and prompts for common workflows.

Remote access is authenticated with two environment variables, one for the daemon URL and one for the authentication token, so a remote daemon can be reached with credentials that are not in the repository configuration. Remote worktrees can then be created and managed over SSH, with multi-host configuration that supports custom ports and identity files, and with Mosh as an alternative transport for better connectivity on poor links.

Outposts have a status, available, unreachable or provisioning, which is the kind of detail that matters when a remote machine is still being created. And there are optional Symphony runtime endpoints, gated behind a feature flag, for workflow orchestration.

The result is that the desktop app, the browser and an agent all drive the same remote machine through the same API. Whether a coding agent runs on your laptop or on a box in a data centre, the interface is the same, and the only thing that changes is where the daemon lives.

## A nightly toolchain, a justfile and a vendored dependency tree

The build and packaging story is the last thing to check, and it is a Rust project that has made some specific choices.

The toolchain badge says nightly, pinned to a date in late 2025, and there is a toolchain file in the repository root, so contributors get the same compiler. The command runner is just, with a justfile at the root, and the development tasks are short: run the application, run the MCP server against a local development daemon, build the documentation. The documentation is an mdBook, with the sources under the docs directory and a task to build them locally, while the live site is a separate GitHub Pages deployment.

The dependency handling is worth noticing, because the repository has a vendor directory. A vendored tree in a Rust project is a deliberate choice, usually made to make builds reproducible or to satisfy a distribution requirement, and it is a heavier commitment than most projects take on.

The rest of the root is configuration that tells you what the project values. There is a changelog configuration for an automated release notes generator, a formatter configuration for TOML files, a Clippy configuration for the linter, a mise file for tool versions, a Prettier configuration, a Homebrew tap directory, a packaging directory, and an agent instruction file. There is also a beads directory and a plans directory, which are the traces of a project that keeps its task tracking and its design notes next to the code.

For installation, the README offers a Homebrew tap for macOS:

```bash
brew install penso/tap/arbor
```

There are also prebuilt release bundles that ship the desktop application with the three companion binaries, and a from-source path that is three commands:

```bash
git clone https://github.com/penso/arbor
cd arbor
just run
``` The feature list also notes a three-pane layout shared between the desktop and web interfaces, thirty-eight themes that sync live between them, and a command palette covering actions, repositories, worktrees, issues, presets and task templates.

## Conclusion

Adopt Arbor if you run several coding agents in parallel across local repositories and want one place to see the worktrees, the terminals and the diffs, because the daemon model is what keeps the sessions alive and lets the same view work over SSH. Do not adopt it if you want a hosted service or a stable public API, because the daemon endpoints and the model context protocol surface are still moving, and the project tracks a nightly Rust toolchain rather than a stable one. Before you build on it, read the crate list, because the daemon and its clients are separate crates with their own version timelines, and check the licence of the vendored dependencies if you intend to redistribute the binaries.

## FAQ

### What is Arbor and what is it built with?

It is a fully native desktop application for agentic coding, written in Rust with the GPUI toolkit, for managing repositories, issue-driven worktrees, embedded terminals, managed processes, diffs, pull request context and coding agent activity.

### Why does Arbor have a daemon at all?

Because the desktop app, the web interface, the command line and the MCP server all talk to the same long-lived daemon. That is what lets terminal sessions survive an application restart, lets the same work be driven over SSH from a remote outpost, and lets an agent create a worktree without a screen.

### Which coding agents can Arbor talk to?

Interactive chat sessions work with agents that speak the agent communication protocol, with Claude, Codex, Pi and Gemini named, and more through a bridge. There is also support for OpenAI-compatible providers, including Ollama, LM Studio, OpenRouter, OpenAI and any endpoint that speaks the chat completions path, with models discovered automatically.

### How does Arbor handle remote machines?

Remote worktrees can be created and managed over SSH, with multi-host configuration supporting custom ports and identity files, and Mosh as an alternative transport. Remote access uses a daemon URL and an authentication token in the environment, and each remote machine has a status of available, unreachable or provisioning.

### How do I install and build Arbor?

There is a Homebrew tap for macOS, release bundles that ship the desktop app with the HTTP daemon, the MCP server and the command line, and a from-source path of cloning the repository and running just run. The documentation is an mdBook built with just docs-build, and the project uses a pinned nightly Rust toolchain with a justfile for tasks.

## Sources

- [License: MIT](https://github.com/penso/arbor/blob/main/LICENSE)
- [penso/arbor on GitHub](https://github.com/penso/arbor)
- [Project website](https://penso.github.io/arbor/)
- [README](https://github.com/penso/arbor/blob/main/README.md)
- [Releases](https://github.com/penso/arbor/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/penso-arbor
