GenerateSaaS

Local mode

Run OpenCompanion with no backend at all - an app on this machine drives the daemon over loopback, with no pairing and no browser approval, under the same policy, grants, and audit log a paired app gets.

Everywhere else in these docs, OpenCompanion pairs with an app over the network: you approve a device, the app dispatches work, your machine runs it. Local mode is the other shape. A desktop app you install on this machine drives the daemon directly over loopback - there is no pairing, no browser approval, and no backend on the wire. Everything runs under one local scope, with the same policy ceiling, granted folders, and audit log a paired app gets.

Reach for it when the app and the daemon live on the same machine and never need the network between them - a desktop app that ships OpenCompanion and supervises it for you.

Local vs. paired

PairedLocal
Who drives itA remote app you paired (--url <backend>)An app on this machine, over loopback
PairingDevice authorization in your browserNone - the app supervises the daemon directly
ScopeOne per paired backendA single local scope
Policy, grants, auditPer backendThe same machinery, under local

Run the daemon locally

An app drives these; you rarely type them yourself. Both take --app-config <path> - a small on-device file naming the product, written by the app.

opencompanion serve --local --app-config <path>      # run the daemon, no backend, app-driven
opencompanion terminal --local --app-config <path>   # open an interactive session, composed on this device

serve --local prints only the loopback port it is listening on and writes a discovery file the app reads to reach it. There is no pairing step and nothing leaves the machine.

Manage the local scope

Everything you can set per paired backend, you set for the local scope by passing --local in place of --url:

opencompanion connect claude-code --local          # connect a CLI for local use
opencompanion disconnect claude-code --local

opencompanion policy show --local                  # the local ceiling, network, work root, granted folders
opencompanion policy set --local --permission-mode read-only --network off
opencompanion policy grant-folder add ~/code/my-project --local
opencompanion policy grant-folder list --local
opencompanion policy grant-folder remove ~/code/my-project --local

opencompanion mcp add linear --local --http https://mcp.linear.app/mcp   # your own MCP servers, local scope
opencompanion mcp list --local
opencompanion mcp remove linear --local

The policy ceiling, granted folders, and audit log all behave exactly as they do for a paired app - they are just scoped to local.

Env-backed MCP servers are terminal-only in local mode. A server you add with mcp add --local --env KEY=VALUE runs in a terminal --local session - the session spawns the CLI and re-hydrates the value into its environment - but a local chat run skips it, because the executor's run request carries no environment at all. mcp list --local marks such a server terminal-only, so you can see which servers a chat run will and will not have.

Read the local scope

opencompanion status --json reports the local scope beside any paired backends - its connected CLIs, its granted folders, and its ceiling - so an app that drives the daemon can read what this machine has in one call.

On this page