← Blog

How I Use Pi Coding Agent Remotely from My Phone

A few days ago I wrote about giving Pi a mobile interface. At that point, Pi Remote let me connect to the Pi coding agents running on my computer, follow their work, send prompts, and start or resume sessions from my phone.

That solved the remote chat problem. It did not quite solve remote development.

Being able to tell an agent to make a change is useful, but I still need to start the application, see the changes the agent made, test out the UI, take screenshots, and sometimes send a file back to the agent. Without that, I still end up having to head to my desktop machine.

So Pi Remote has changed fairly quickly. It is still a mobile interface for the exact Pi processes running on my computer, but it is becoming more of a private remote development workspace around them.

My current requirements are:

Pi runs on my development machine

The broker runs as a standalone user service on that machine. Each interactive Pi process loads an extension that registers the live session with the broker and reports its current state. The browser connects to the broker and receives conversation snapshots, streamed assistant output, thinking state, and tool activity.

When I send a prompt from my phone, it is routed back to the selected Pi process and submitted through Pi’s extension APIs. That process still owns the model, tools, conversation, and agent loop.

If I close the PWA, lose my phone connection, or restart the Pi Remote broker, Pi continues working. The terminal session remains authoritative.

Private remote access with Tailscale

The Pi Remote broker binds to 127.0.0.1. I do not expose it directly to the public internet.

For remote access, I use Tailscale Serve to make the local web interface available over HTTPS inside my tailnet:

sudo tailscale serve --bg --yes --https=8788 http://127.0.0.1:8787

I open the resulting URL in Safari and install the progressive web app on my iPhone home screen. Tailscale supplies the identity of the connecting user, and Pi Remote checks that identity. Other private routes can use browser-device pairing approved from a locally authenticated Pi session.

Remote access to a coding agent needs to be treated as machine access. Pi Remote does not provide a general shell endpoint, but a prompt can cause Pi’s tools to run commands, read files, and modify code. I would not expose it through Tailscale Funnel or a public reverse proxy.

Projects instead of a flat list of agents

The first version of Pi Remote was mostly organized around running sessions. That worked, but it became noisy once I had several agents working across several repositories.

The dashboard is now organized around projects. A project bookmarks an approved directory and provides a home for:

I can star the projects I use most often and put them in the order I want. A Rails application, Hugo website, and Pi extension project remain separate even when each has several sessions running.

This better matches how I think about the work. The project is the long-lived thing. Individual agent sessions come and go inside it.

Starting development services from my phone

Each project can now have saved services. A service is stored as an executable and an argument array, runs from the project root, and does not go through a shell. For a Rails project, the saved service might simply run:

bin/dev

I can start or stop that service from the project page. It runs in a separate detached tmux server, so it survives browser disconnects and broker restarts.

Pi Remote also shows the service output. If Rails fails during boot, Vite cannot bind its port, or Hugo reports a template error, I can inspect that without opening an SSH client and finding the right terminal session.

This is intentionally not a general process manager. Services have to be configured ahead of time for an approved project. Pi Remote can run those trusted commands, but it does not expose an arbitrary command field in the browser.

Opening local development previews remotely

Starting the application solves only half of the problem. I need to be able to run dev environments and view them from my phone.

A project service can declare a preview port. When the service starts, Pi Remote configures a private Tailscale Serve handler for that local port and displays an Open site action on the project and its running agent sessions.

The preview stays inside my tailnet. Pi Remote does not use Tailscale Funnel, and it keeps track of the exact Serve handlers it creates so it does not replace unrelated Tailscale configuration.

For applications that use host-based tenants, a service can also have Tailscale Service hostnames pointing to the same local port. The application still needs to allow those hostnames, but this gives me a usable HTTPS development URL rather than trying to work around localhost from the phone.

This changed the remote workflow considerably. I can now ask Pi to change a page, then I can open the development site on my phone, review the result, and send another instruction without going back to the computer. This also has the unintended advantage of easily viewing how things look and feel on an actual mobile device.

Giving the Pi coding agent the same preview

The preview URL is useful to me, but it is also useful to the agent.

Before an agent run, the Pi Remote extension finds the nearest saved project for the session directory. If that project has a running preview, the extension adds the preview URL to the turn’s system prompt.

The agent is told to use the existing HTTPS preview for browser review rather than starting another development server. This is especially useful when an agent has browser tools available. It can make a change, inspect the same site I can open from my phone, and continue refining it.

The /preview command also shows the current project’s service state and available URLs inside the local Pi interface.

I did not want the remote browser and the agent inventing separate ways to reach the application. The project owns the service and preview. Both of us use it.

Sending files and images to Pi remotely

Pi Remote originally supported image prompts. It now accepts other files as well.

I can attach up to four files from the composer. Supported images are sent to Pi through its native image flow. Other attachments are written to a private directory on my machine and the selected agent receives their absolute paths in the prompt.

The files are not copied into the project automatically. The agent can inspect them and decide what to do.

This has been useful for screenshots, documents, and files that arrive while I am away from my desk. It is also much nicer than trying to describe a visual issue in a long phone message.

Using extension commands from the remote composer

My Pi setup depends heavily on extensions. A session may have commands for project management, previews, usage information, agent delegation, or another project-specific workflow.

Typing / in the Pi Remote composer searches the extension commands registered in that exact session. Selecting one inserts the command so I can add arguments before sending it.

These are not commands reimplemented by the web application. They execute through Pi’s native extension command context, including while the agent is working when the command supports that.

This keeps Pi Remote from needing to understand every workflow I add to Pi. The selected Pi session remains responsible for the commands it exposes.

Using the Pi coding agent remotely from my phone

I use Pi Remote from both my phone and desktop browser, although the terminal is still my main interface when I am at the computer.

On mobile, I can swipe between sessions, use voice input, attach files, open a project preview, and receive Web Push notifications when an agent finishes. The notification includes the session name and a short excerpt of the final response, which is useful when several agents are running.

On desktop, the persistent project and session sidebar makes it easier to see everything at once. Keyboard shortcuts and the command palette handle session switching, model and reasoning controls, cloning, forking, renaming, and starting new sessions without moving through several screens.

Composer drafts are stored per session. If I begin writing a message, switch to another agent, and come back, the original draft is still there.

What I use it for now

My normal remote Pi coding agent workflow now looks something like this:

  1. Open Pi Remote from my iPhone home screen.
  2. Choose a project and start or resume a Pi session.
  3. Start the project’s development service if it is not already running.
  4. Ask Pi to work on a change using text, voice, or an attachment.
  5. Follow the tool activity or leave the app and wait for a notification.
  6. Open the private development preview and review the result.
  7. Send a follow-up to the same Pi process.

I am not going to do an entire day of development from my phone. Detailed code review and larger decisions are still better at my desk.

What this does remove is the need to be at my desk for every small interaction around a long-running agent. I can start work, check on it, inspect the application, and give direction while I am elsewhere.

Where Pi Remote is now

The first version of Pi Remote gave me remote access to a Pi coding agent session. The current version includes more of the development environment around each session: projects, persistent sessions, saved services, logs, private previews, attachments, extension commands, voice, and notifications.

It is still deliberately private and single-machine. The broker runs locally. Project services run with my user account. Tailscale provides the private network. Pi remains the authoritative process for every conversation and agent action.