> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mspilot.io/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> MSPilot enrolls technician Windows machines and Apple Silicon Macs so Claude Desktop and ChatGPT run through one governed gateway. Seat words are standard seat and power seat. ConnectWise PSA import is not available. HIPAA is not a self-serve switch.

# Claude and ChatGPT on Macs

> Install and update Claude Desktop and ChatGPT on Macs from your RMM or MDM.

Two scripts install Claude Desktop and ChatGPT on Macs and keep them current: `install-claude-macos.sh` and `install-chatgpt-macos.sh`. Admin offers them to copy into your RMM, or, for N-sight RMM and without an RMM, to download as `mspilot-install-claude-macos.sh` and `mspilot-install-chatgpt-macos.sh`. They are separate from the [agent enroll script](/agent/macos), which installs only the MSPilot agent.

## What the scripts do

Each script runs as root and works on `/Applications/Claude.app` or `/Applications/ChatGPT.app`:

1. It reads the version that is installed, if any.
2. It asks the vendor's own update feed for the newest version. Anthropic rolls Claude releases out in stages, so the script asks the feed the same way the app does, and Macs can get a new version in different weeks. The script sends a hash derived from the Mac's hardware UUID, not the UUID itself.
3. When the app is current, it changes nothing.
4. Otherwise it downloads the vendor's package and checks it before it installs anything: signed with the vendor's Developer ID Installer certificate (Anthropic PBC, Team ID `Q6L2SF6YDW`; OpenAI OpCo, LLC, Team ID `2DC432GLL2`), notarized by Apple, and holding the expected app and version.
5. It installs the package with macOS `installer`, then checks the installed app's signature and version again.

The packages come straight from Anthropic and OpenAI, not from MSPilot. The scripts download over HTTPS only.

When the app is open, the script does not upgrade it. It reports `status=deferred_running`, and the next scheduled run upgrades it. The script checks before the download and again right before it installs, because the download can take minutes.

After an install or upgrade on a Mac with the MSPilot agent, the script starts the signed-in user's config pull, so the new app is pointed at the gateway right away. Other users get it at their next sign-in, then hourly.

## Requirements

* Tested on macOS 15 and later. Claude and ChatGPT support macOS 13, and the scripts stop on anything older.
* ChatGPT needs an Apple Silicon Mac. Claude runs on Apple Silicon and Intel Macs, but the MSPilot agent itself needs Apple Silicon.
* Root. Run the scripts as root, like the enroll script. Nobody needs to be signed in.

## Get the scripts

1. Open the client and go to **Deployment**, or open **Scripts** and pick the client.
2. Pick **macOS**.
3. Tick **Claude Desktop**, **ChatGPT**, or both: under **AI applications** on **Deployment**, or under **AI apps to install** on **Scripts**, where both start ticked. You get one script per app.

| Where | What you get |
| - | - |
| NinjaOne, Datto, ConnectWise RMM, Level, Syncro | A script to copy into the RMM |
| N-sight RMM | A `.sh` file to download and upload to an Automated Task |
| No RMM | A `.sh` file to download and run on one Mac |

Save each script in your RMM the same way as the enroll script, with the fields on your RMM's page:

| RMM | How it runs as root |
| - | - |
| [NinjaOne](/integrations/rmm/ninja-one) | Language **ShellScript**, Operating System Mac, **Run as: System** |
| [Datto](/integrations/rmm/datto) | A **Shell (Unix/macOS)** Component, run as a **Quick Job**. Quick jobs run as root on macOS. |
| [ConnectWise RMM](/integrations/rmm/connectwise-rmm) | **Function → Bash Script**, **Operating System: MacOs**, then **Function → Script Log**, message `%output%`, so the result line shows in the task log |
| [Level](/integrations/rmm/level) | A Bash script with **Run as: Local system** |
| [Syncro](/integrations/rmm/syncro) | A **Mac Script** with **Run as: System** |
| [N-sight RMM](/integrations/rmm/n-sight) | An **Automated Task** for macOS with the downloaded `.sh` |

Each package is several hundred megabytes. On a slow link the script tries the package download at most twice, 20 minutes each, before it reports `download_failed`, and the install itself takes more time after that. Give the job a timeout of at least 1 hour (3600 seconds).

On one Mac without an RMM, download the file, then run it in Terminal and type the Mac's administrator password:

```bash theme={"system"}
sudo bash ~/Downloads/mspilot-install-claude-macos.sh
sudo bash ~/Downloads/mspilot-install-chatgpt-macos.sh
```

## Schedule it weekly

Schedule each script weekly in your RMM, or in your [MDM](#from-an-mdm). A run installs the app when it is missing, upgrades it when the vendor has a newer version, and otherwise changes nothing. Users without administrator rights cannot install the apps' own updates into `/Applications`, so the weekly run is what keeps the apps current.

## Results

A successful run prints one `claude_install_ok` or `chatgpt_install_ok` line and exits 0. A ChatGPT run can also print a [warning line](#chatgpt-package-behind-its-feed).

```text theme={"system"}
claude_install_ok status=installed version=<version>
chatgpt_install_ok status=already_current version=<version>
```

| Status | Meaning |
| - | - |
| `status=installed` | The app was missing, or was ChatGPT Classic, and is now installed. |
| `status=upgraded` | The app was older and is now upgraded. |
| `status=already_current` | The app is current. Nothing changed. |
| `status=deferred_running` | The app was open, so the upgrade was skipped. The next run upgrades it. `version` is the version on the Mac. |

The same `status=deferred_running` week after week means the app never closes on that Mac, or a process imitates it. Check the Mac.

A failure prints `claude_install_failed reason=<reason>` or `chatgpt_install_failed reason=<reason>` and exits 1. For every reason above `installer_failed` in the table, the app on the Mac is unchanged. `installer_failed` and `post_install_verify_failed` come after macOS `installer` started; with `post_install_verify_failed` the package was installed but the app did not verify. Check the Mac in both cases.

| Reason | Meaning |
| - | - |
| `macos_only` | The script ran on something other than a Mac. |
| `root_required` | The script did not run as root. Set the RMM script to run as root, as in the table above. |
| `macos_13_required` | The Mac runs a macOS older than 13. |
| `apple_silicon_required` | ChatGPT only: the Mac has an Intel processor. |
| `macos_too_old` | ChatGPT only: OpenAI's newest ChatGPT needs a newer macOS than this Mac has. |
| `unexpected_app_at_path` | `/Applications/Claude.app` or `/Applications/ChatGPT.app` is a link, another app, or has no readable version. The script does not replace it. |
| `classic_path_occupied` | ChatGPT only: see [ChatGPT Classic](#chatgpt-classic). |
| `work_dir_failed` | The script could not create its working folder in `/private/tmp`. |
| `feed_unreachable` | The script could not reach the vendor's update feed. |
| `feed_invalid` | The feed's answer was not what the script expects, for example an unexpected version or download link. |
| `download_failed` | The package download failed. |
| `signature_mismatch` | The download was not the vendor's notarized package: wrong signature, wrong Team ID, or not notarized. |
| `package_mismatch` | The package does not hold the expected app or version. |
| `installer_failed` | macOS `installer` failed. Its output is in the job output, each line starting with `installer:`. |
| `post_install_verify_failed` | After the install, the app's signature or version did not match. |

### ChatGPT package behind its feed

OpenAI publishes one unversioned `ChatGPT.pkg`. After a release it can trail OpenAI's update feed for hours. The script installs or upgrades whenever that package is newer than the app on the Mac, and otherwise reports `status=already_current`. When the script checks the package and it is older than the feed's newest version, the script also prints this line and still exits 0. It does not check the package, and prints no warning, when the Mac already has the feed's version or the app is open.

```text theme={"system"}
chatgpt_install_warning pkg_behind_feed=<package version> feed=<feed version>
```

The run installs the package's version only if it is newer than the Mac's, and a later run picks up the newer one. The same warning week after week means OpenAI stopped updating that package.

The script remembers the last package it checked in `/Library/Application Support/MSPilot/apps/chatgpt-pkg.state`, so an unchanged package is not downloaded again. The file is only a cache. When it is missing, or its owner or permissions are not what the script wrote, the script downloads the package again.

## ChatGPT Classic

When `/Applications/ChatGPT.app` is the older ChatGPT Classic, OpenAI's package keeps it and renames it to `ChatGPT Classic.app`, then installs the new ChatGPT. When `/Applications/ChatGPT Classic.app` already exists, the package cannot rename the old app, so the script stops with `classic_path_occupied`. Remove or rename one of the two apps, then run the script again.

MSPilot configures only the new ChatGPT. It does not configure or restart ChatGPT Classic.

## N-sight RMM: install from a URL

For N-sight RMM, **Deployment** and **Scripts** (once you pick the client) also show direct links to the vendors' packages when Admin can look them up. The N-sight guide for the MDM install method lists them too, as optional steps. You can use them with N-sight's **Install Application from URL** Automated Task: put the link in **Command Line** and run the task once. The URL task installs once; the weekly script keeps the app current.

To deploy the agent itself from N-sight Device Management for Apple, see [macOS MDM](/integrations/mdm/macos).

## From an MDM

To keep the apps current from your MDM, run the same scripts there. Get them on **Deployment** or **Scripts** as above, add each one to your MDM as a shell script that runs as root, and schedule it weekly with a timeout of at least 1 hour. On **Deployment**, the MDM install method shows the same script buttons above the MDM steps.

Or deploy the vendors' signed packages from your MDM instead of running the scripts:

* Claude: the `.pkg` from Anthropic's [Deploy Claude Desktop for macOS](https://support.claude.com/en/articles/12611117-deploy-claude-desktop-for-macos).
* ChatGPT: `https://persistent.oaistatic.com/codex-app-prod/ChatGPT.pkg`. OpenAI's [app updates guide](https://learn.chatgpt.com/docs/enterprise/manage-app-updates) covers the app's updater.

If your MDM manages the app versions, turn off the apps' own updaters:

* Claude reads the managed preference `disableAutoUpdates` in the domain `com.anthropic.claudefordesktop`. See Anthropic's [enterprise configuration](https://support.claude.com/en/articles/12622667-enterprise-configuration-for-claude-desktop).
* ChatGPT reads `[features] in_app_updates = false` from `requirements.toml`, through ChatGPT's [managed configuration](https://learn.chatgpt.com/codex/enterprise/managed-configuration) or the MDM domain `com.openai.codex` key `requirements_toml_base64`.

With the updaters off, your MDM, or the weekly scripts, must deliver each new version.
