Summary
Introduce an official mactools command-line tool backed by a versioned, authenticated local IPC contract
The CLI should discover and invoke the same canonical actions used by Unified Search, global shortcuts, Automation, Action Grid, gestures, Run Links, and App Intents.
Canonical actions remain the domain model. Run Links remain the lightweight deep-link interface. The CLI becomes an additional programmatic surface with structured input, output, completion, and error behavior.
Decision Requested
This RFC asks the project to decide:
- Whether MacTools should ship an official CLI
- Which local IPC architecture should connect the CLI to the running host
- How CLI action eligibility relates to existing external-invocation policy
- How the CLI locates or starts the MacTools host
- How the binary is distributed and placed on the user's shell path
- Which commands and guarantees belong in the first version
This RFC does not authorize a network server or remote-control API.
Motivation
Run Links are appropriate for:
- Clickable integrations
- Apple Shortcuts
- Launchers
- Documentation
- Fire-and-forget shell commands
- Stored parameter presets
They are not sufficient for:
- Listing installed actions
- Describing action parameters
- Querying availability
- Passing typed parameters directly
- Receiving structured results
- Returning reliable shell exit codes
- Waiting for completion
- Cancelling cancellable work
- Machine-readable scripting
- Future local agent integrations
A CLI would make MacTools useful from:
- Terminal scripts
- Shell aliases
- Developer tooling
- Alfred, Raycast, Hammerspoon, and similar tools
- Test automation
- Local agents
- A future MCP adapter
- Support and diagnostic workflows
Architectural Invariants
- Plugins continue to publish canonical actions through the existing action registry.
- The CLI does not load plugin bundles.
- The CLI does not implement plugin behavior.
- The CLI does not bypass availability, permission, confirmation, concurrency, or timeout policies.
- The host process remains authoritative for installed plugins and runtime state.
- The CLI communicates only through a local authenticated channel.
- No TCP port or local HTTP server is introduced.
- Run Links remain supported.
- Existing action references remain stable.
- Sensitive action values are never placed in URLs or ordinary command-line arguments.
Proposed Command Surface
The initial command groups should be:
General
mactools version
mactools doctor
mactools help
Actions
mactools actions list
mactools actions describe <provider/action>
mactools actions availability <provider/action>
mactools actions run <provider/action>
mactools actions run <provider/action> --parameter name=value
mactools actions run <provider/action> --input-json <path>
mactools actions run <provider/action> --json
Workflows
Workflows remain canonical actions, but convenience commands improve usability:
mactools workflows list
mactools workflows describe <name-or-id>
mactools workflows run <name-or-id>
mactools workflows history <name-or-id>
Plugins
Read-only plugin status may be useful:
mactools plugins list
mactools plugins describe <plugin-id>
mactools plugins doctor <plugin-id>
Installing, updating, and uninstalling plugins should remain outside the first CLI version.
Output Behavior
Human-Readable Mode
Default output should be concise and suitable for interactive terminal use.
Examples of result categories:
- Completed
- Started
- Cancelled
- Unavailable
- Confirmation denied
- Timed out
- Invalid parameters
- Host unavailable
- Provider changed
JSON Mode
--json should produce a versioned object containing:
- Protocol version
- Request ID
- Action reference
- Invocation source
- Start and finish timestamps
- Outcome category
- User-facing message
- Structured rejection category
The output must not contain sensitive parameter values.
Exit Codes
Define stable exit-code categories for:
- Success
- Invalid command or input
- Unknown action
- Action unavailable
- Confirmation denied or unavailable
- Action failure
- Timeout
- Cancellation
- Host or transport failure
- Protocol incompatibility
Exact numeric values should be selected during implementation and documented as part of the CLI contract.
Execution Semantics
Add a distinct .cli action-execution source.
The first version should:
- Wait for validation and confirmation
- Wait for ordinary action completion by default
- Return after durable background work is accepted when the action owns its own progress UI
- Allow
--no-wait only when semantics are unambiguous
- Send cancellation when the CLI receives an interrupt and the action is cancellable
- Preserve the action's configured timeout
- Display host-owned confirmation UI for confirmation-required actions
- Fail rather than silently approve when confirmation UI cannot be presented
Fine-grained progress streaming is not required for the first version. The initial protocol may report accepted, started, and final states. A future protocol version can add progress events.
Initial Action Eligibility
Use a conservative policy for the first version.
An action may be run from the CLI only when:
- It is published in the action catalog
- It is currently registered
- Its parameters validate
- It is currently available
- Its execution mode is supported
- It is eligible for external invocation under the current policy
- It contains no unsupported sensitive parameter transport
- The provider has not excluded the CLI surface
Add ActionExposureSurface.cli so providers can explicitly exclude a CLI invocation.
The RFC should decide whether a future dedicated CLI policy is needed for actions that should be available to a signed local CLI but not to URL-based Run Links.
Sensitive Parameters
Do not encourage secrets on the command line because shell histories and process listings may expose them.
Sensitive values should use one of:
- Standard input
- A permission-restricted input file
- A future host-owned secure prompt
- A Keychain-backed saved preset
The host must continue validating parameter privacy metadata.
Sensitive parameter values must never appear in:
- Process arguments
- Logs
- Diagnostics
- JSON output
- Action history
- Error messages
Local Transport Spike
Before implementing the full CLI, compare these architectures.
Option A: User-Scoped Bundled LaunchAgent Using XPC
Potential benefits:
- Discoverable local service
- Launch-on-demand behavior
- Explicit bidirectional interface
- Strong code-signing validation
- Clear service lifecycle
Costs:
- Additional process
- Service Management registration
- Upgrade and removal behavior
- Coordination with the GUI host and plugin runtime
Option B: GUI-Owned Authenticated IPC Endpoint
Potential benefits:
- Fewer long-running processes
- The action registry stays directly inside the existing host
- Simpler ownership after the app is running
Costs:
- Endpoint discovery
- Secure app-launch handoff
- Stale endpoint cleanup
- Peer validation
- More complicated behavior when the app is not running
Option C: User-Owned Unix-Domain Socket
Potential benefits:
- Simple request and response protocol
- Natural streaming and cancellation
- Easy use from multiple languages
Costs:
- Custom authentication
- Socket lifecycle and permissions
- Peer-identity verification
- More custom security code than XPC
The spike should select an option based on:
- Same-user and same-team validation
- Launch behavior
- Upgrade behavior
- Cancellation
- Streaming
- Testability
- Failure recovery
- App Sandbox and signing constraints
- Removal behavior
Do not select a transport only because it is quickest to prototype.
Security Requirements
- Accept connections only from the current user.
- Validate the CLI's code-signing identity where supported.
- Fail closed when identity cannot be established.
- Use a versioned, explicit IPC interface.
- Bound request and response sizes.
- Reject unknown fields or unsupported protocol versions safely.
- Validate every action reference through the registry.
- Revalidate provider generation and availability before execution.
- Preserve confirmation policy.
- Never expose arbitrary Swift invocation, selectors, shell execution, or plugin internals.
- Do not add a general "run arbitrary command" endpoint.
- Keep an optional redacted audit entry for CLI-originated actions.
- Prevent recursive CLI-to-action-to-CLI invocation loops where detectable.
Host Lifecycle
When MacTools is not running, the CLI should:
- Locate the installed MacTools application.
- Launch or activate the host without opening unnecessary windows.
- Wait for action-registry readiness with a bounded timeout.
- Negotiate the local protocol version.
- Execute or return a clear startup error.
The CLI must not independently inspect or load installed plugin bundles.
If no graphical user session is available, actions requiring UI or confirmation should fail clearly.
Distribution
Ship a signed CLI binary with the MacTools application.
Evaluate these installation paths:
- Homebrew exposes the bundled binary automatically.
- The app provides an "Install Command Line Tool" or "Show Setup Command" action.
- Users can add a symlink under
~/.local/bin.
- Advanced users can invoke the binary directly from the app bundle.
Avoid introducing a privileged helper solely to create a symlink.
The CLI and application should report compatible protocol and build versions through mactools version and mactools doctor.
Implementation Phases
Phase 0: Transport and Security Spike
- Compare the candidate IPC architectures.
- Implement version handshake.
- Validate same-user and same-team behavior.
- Test app launch and registry readiness.
- Test stale or incompatible clients.
- Document the selected architecture.
Phase 1: Read-Only Discovery
version
doctor
actions list
actions describe
actions availability
workflows list
- Human-readable and JSON output
Phase 2: Conservative Execution
- Run parameterless externally eligible actions.
- Wait for completion.
- Return structured result and exit code.
- Preserve confirmation behavior.
- Add cancellation for cancellable actions.
Phase 3: Typed Parameters
- Validate typed parameter input.
- Support JSON input.
- Support secure sensitive-value input.
- Add saved-preset references where appropriate.
Phase 4: Richer Integrations
- Optional progress events
- Action and workflow history
- MCP adapter
- Better launcher integrations
- Additional authenticated local clients
Test Coverage
Include tests for:
- Protocol-version mismatch
- Unsigned or wrong-team client
- Wrong user
- Host not installed
- Host not running
- Host launch timeout
- Registry startup delay
- Unknown action
- Invalid parameters
- Unavailable action
- Permission failure
- Confirmation approval and denial
- Confirmation unavailable
- External invocation excluded
- Provider changing during execution
- Concurrent invocation policy
- Timeout
- Cancellation
- Sensitive-value redaction
- JSON schema stability
- Exit codes
- App and CLI upgrade ordering
Acceptance Criteria for the RFC
- The product role of the CLI is approved.
- Canonical actions remain the sole execution domain model.
- Run Links remain supported.
- One local transport architecture is selected.
- Client-identity and user-identity requirements are documented.
- Host-startup behavior is decided.
- Initial action-eligibility policy is decided.
- Sensitive-parameter transport is decided.
- Initial command and JSON contracts are approved.
- Distribution and shell-path behavior are decided.
- Phase 0 can proceed without committing to a public remote API.
Non-Goals
- Remote access over the network
- A REST server
- A public cloud API
- Replacing the GUI
- Replacing Run Links
- Loading plugins inside the CLI
- Allowing arbitrary code execution
- Root or system-wide control
- Plugin installation or update in the first version
- Guaranteeing headless execution for actions that require a graphical session
- Declaring the first IPC protocol permanently stable for third parties
Open Questions
- Should CLI eligibility initially reuse Run Link external policy, or should a separate opt-in be required?
- Should the host, a LaunchAgent, or a broker own the IPC listener?
- Should the CLI launch MacTools automatically by default?
- Which actions should be visible but not runnable?
- Should workflow conveniences be aliases over actions or separate IPC operations?
- How should fine-grained progress evolve without changing the current action ABI prematurely?
- What is the preferred Homebrew and non-Homebrew installation path?
Summary
Introduce an official
mactoolscommand-line tool backed by a versioned, authenticated local IPC contractThe CLI should discover and invoke the same canonical actions used by Unified Search, global shortcuts, Automation, Action Grid, gestures, Run Links, and App Intents.
Canonical actions remain the domain model. Run Links remain the lightweight deep-link interface. The CLI becomes an additional programmatic surface with structured input, output, completion, and error behavior.
Decision Requested
This RFC asks the project to decide:
This RFC does not authorize a network server or remote-control API.
Motivation
Run Links are appropriate for:
They are not sufficient for:
A CLI would make MacTools useful from:
Architectural Invariants
Proposed Command Surface
The initial command groups should be:
General
mactools versionmactools doctormactools helpActions
mactools actions listmactools actions describe <provider/action>mactools actions availability <provider/action>mactools actions run <provider/action>mactools actions run <provider/action> --parameter name=valuemactools actions run <provider/action> --input-json <path>mactools actions run <provider/action> --jsonWorkflows
Workflows remain canonical actions, but convenience commands improve usability:
mactools workflows listmactools workflows describe <name-or-id>mactools workflows run <name-or-id>mactools workflows history <name-or-id>Plugins
Read-only plugin status may be useful:
mactools plugins listmactools plugins describe <plugin-id>mactools plugins doctor <plugin-id>Installing, updating, and uninstalling plugins should remain outside the first CLI version.
Output Behavior
Human-Readable Mode
Default output should be concise and suitable for interactive terminal use.
Examples of result categories:
JSON Mode
--jsonshould produce a versioned object containing:The output must not contain sensitive parameter values.
Exit Codes
Define stable exit-code categories for:
Exact numeric values should be selected during implementation and documented as part of the CLI contract.
Execution Semantics
Add a distinct
.cliaction-execution source.The first version should:
--no-waitonly when semantics are unambiguousFine-grained progress streaming is not required for the first version. The initial protocol may report accepted, started, and final states. A future protocol version can add progress events.
Initial Action Eligibility
Use a conservative policy for the first version.
An action may be run from the CLI only when:
Add
ActionExposureSurface.cliso providers can explicitly exclude a CLI invocation.The RFC should decide whether a future dedicated CLI policy is needed for actions that should be available to a signed local CLI but not to URL-based Run Links.
Sensitive Parameters
Do not encourage secrets on the command line because shell histories and process listings may expose them.
Sensitive values should use one of:
The host must continue validating parameter privacy metadata.
Sensitive parameter values must never appear in:
Local Transport Spike
Before implementing the full CLI, compare these architectures.
Option A: User-Scoped Bundled LaunchAgent Using XPC
Potential benefits:
Costs:
Option B: GUI-Owned Authenticated IPC Endpoint
Potential benefits:
Costs:
Option C: User-Owned Unix-Domain Socket
Potential benefits:
Costs:
The spike should select an option based on:
Security Requirements
Host Lifecycle
When MacTools is not running, the CLI should:
The CLI must not independently inspect or load installed plugin bundles.
If no graphical user session is available, actions requiring UI or confirmation should fail clearly.
Distribution
Ship a signed CLI binary with the MacTools application.
Evaluate these installation paths:
~/.local/bin.Avoid introducing a privileged helper solely to create a symlink.
The CLI and application should report compatible protocol and build versions through
mactools versionandmactools doctor.Implementation Phases
Phase 0: Transport and Security Spike
Phase 1: Read-Only Discovery
versiondoctoractions listactions describeactions availabilityworkflows listPhase 2: Conservative Execution
Phase 3: Typed Parameters
Phase 4: Richer Integrations
Test Coverage
Include tests for:
Acceptance Criteria for the RFC
Non-Goals
Open Questions