Off by default. Turn it on in Settings → Integration. The master switch closes every adapter at once; each adapter also has its own switch.
What external access is
Other apps can ask Proxy Manager to do a small, fixed set of things: turn routing on or off, edit the hostname targets, edit per-app rules, read status, and open a window or a specific Settings pane. Everything else stays in the app.
The feature exists for automation — a Shortcut that toggles routing, a launcher that opens the Targets pane, a script that adds a host before a build. It is not a remote-control API for the whole app.
What can be controlled
| Action | Arguments | Kind |
|---|---|---|
ping | — | read |
capabilities | — | read |
status | — | read |
routing.explain | host:string, bundleID:string? | read |
routing.enable | — | policy |
routing.disable | — | policy |
routing.toggle | — | policy |
routing.retry | — | policy |
targets.list | enabledOnly:bool? | read |
targets.add | pattern:string, enabled:bool? | policy |
targets.remove | id:uuid?, pattern:string? | policy |
targets.update | id:uuid, pattern:string?, enabled:bool? | policy |
targets.clear | confirm:bool | policy |
presets.list | — | read |
presets.apply | name:string | policy |
apps.list | — | read |
apps.setEnabled | enabled:bool | policy |
apps.setDefault | mode:enum | policy |
apps.rule.set | key:string, keyKind:enum, mode:enum, enabled:bool? | policy |
apps.rule.remove | id:uuid?, key:string?, keyKind:enum? | policy |
apps.resolve | bundleID:string?, path:string?, pid:int? | read |
ui.open | pane:enum, section:enum?, revealPattern:string?, revealAppRuleID:uuid? | ui |
app.activate | pane:enum? | ui |
Mutations are idempotent and report whether they changed anything. Arguments marked ? are optional. Unknown arguments are rejected, so a typo fails instead of being ignored.
Kind is read, ui or policy. A few rules are not visible in the table:
targets.removeandapps.rule.removetake exactly one selector.targets.clearrequiresconfirm=true.apps.rule.setnever turns per-app routing on; useapps.setEnabledor the Shortcut.ui.openwith asectionrequirespane=settings.
Turn it on
Settings → Integration has one master switch and a switch per adapter:
| Switch | What it closes |
|---|---|
| Allow external control | everything: the local socket, the XPC agent, URL links and Shortcuts |
| Apps and CLI (XPC) | the com.proxymanager.control service and its socket |
| URL links | proxymanager:// delivery |
| Shortcuts and Siri | the App Intents |
| Keep an audit log | audit writes only; requests still run |
Turning the master switch off stops the endpoint and unregisters the agent. Approvals are kept, so turning it back on does not ask again. revert.sh goes further and also removes the socket, token and approval file.
Who is allowed
- Every app is approved once. The first request shows a sheet with Allow Control, Read Only or Deny. The grant is stored against the app's code-signing designated requirement, so a different binary claiming the same bundle identifier must ask again. Revoke any approval in Settings → Integration.
- Two scopes. Read only can list targets, read status and explain routing. Control can also change routing, targets and per-app rules.
- No administrator prompts, ever. An external call is never treated as a present user. If a privileged action were needed it would be deferred, exactly as for a background launch. A remote
enablethat could raise the password dialog would be a phishing primitive. - Rate limited and audited. 240 reads and 30 mutations per minute per caller, with a tighter limit on
routing.toggle. Requests land inintegration-audit.jsonl(0600) with redacted arguments. - The boundary is your user account. The socket is 0600 and the agent checks the caller's signature, but a process already running as you can read the token. This protects against accidental control and unapproved apps, not against malware running as you.
What is never exposed
- The tunnel: endpoints, SSH credentials, the Keychain password.
- The local proxy listener's bind host or port, and the system-proxy internals.
- Shell/GUI environment injection, the privileged helper, Login Items.
- Appearance, monitoring history, config import or reset.
Those stay UI-only even for an approved Control caller.
Errors
Every response carries a stable code: bad_request, unknown_action, invalid_argument (with the offending field), unauthorized, forbidden, not_found, conflict, busy, timeout, unavailable, unsupported, shutting_down, requires_user_action, internal.
Pick an adapter
- URL links — zero dependencies, no reply channel, routing and windows only.
- Shortcuts & Siri — the OS-native path for people.
- Apps & CLI — typed request/reply for other software.