Skip to content

Cursor upgrade guides

Upgrading Cursor safely takes three moves: record a baseline of the current build (its version, extensions, MCP servers, and the project’s test results), update and compare the new build against that baseline, and keep a hash-checked copy of the previous build so a bad update costs minutes. Cursor updates itself by default.

This page is for the developer whose Cursor updated itself overnight and the tech lead who has to decide whether the team follows. The morning after an update, the agent stops using a project rule, one extension fails to load, and the Postgres MCP server shows no tools. Without a record of how things looked yesterday, you cannot tell whether the update broke them or they were already broken.

What you get from this Cursor upgrade guide

Section titled “What you get from this Cursor upgrade guide”
  • A five-minute pre-update routine that archives your Cursor data and records a baseline you can diff against.
  • A copy-paste prompt that makes the agent record that baseline, and a second one that re-runs it on the new build and reports every difference.
  • A pass criterion that comes from exit codes and lists, not from reading the agent’s output line by line.
  • Rollback steps for macOS, Linux and Windows that install a previous build whose SHA-256 hash, or on Windows its code signature, you check first.
  • A recovery entry for each common update failure, and a third prompt that turns a regression into a bug report.

Record the build before anything changes. Run this in a terminal:

Terminal window
cursor --version

The first line is the version, the second is the commit hash of the build, and the third is the CPU architecture. Write all three down with the date. The commit hash matters most for rollback: Cursor’s download URLs are keyed by it, and the Homebrew cask records it for each release the cask was bumped to.

If cursor is not on your PATH, fix that first with the steps in installing Cursor. The rest of this page uses the command.

Cursor downloads and installs its own updates. The Homebrew cask marks it auto_updates, which is why brew upgrade leaves it alone: the app, not your package manager, decides when a new build arrives.

Cursor is built on VS Code, which controls updates with the update.mode setting. Cursor’s macOS build, however, ships its own updater: the cask removes ToDesktop’s ShipIt cache and a cursor-updater cache when it uninstalls Cursor. So treat the key as something to test on your build, not a guarantee. Add it to your user settings.json (open the Command Palette and run Preferences: Open User Settings (JSON)):

{
"update.mode": "manual"
}
ValueWhat VS Code’s setting doesUse it when
defaultChecks for updates automatically and periodicallyYou want updates as they arrive and have a baseline recorded
startChecks only on startupYou restart Cursor at a predictable time, such as Monday morning
manualNo background checks; updates only when you check yourselfYou are holding on a known-good build during a deadline or after a rollback
noneDisables updatesNever on a daily machine: you also stop receiving security fixes

These values and meanings come from VS Code’s source. Confirm that your Cursor build honours the key: after you set manual, the Settings search for update.mode should show the value you chose, and Cursor should not offer a restart-to-update prompt until you check for updates yourself. If a restart prompt appears anyway, your build ignores the key; the only reliable hold is then the rollback below, repeated whenever it updates.

On macOS, of the paths the Homebrew cask deletes when it removes Cursor completely, two hold your own data; Linux and Windows keep the same two in VS Code’s usual places: the application-data directory (settings, keybindings, snippets, and per-workspace state) and ~/.cursor (which holds the global ~/.cursor/mcp.json). Archive both while Cursor is closed.

  1. Quit Cursor completely, not only its window. On macOS, use Cursor › Quit Cursor.

  2. Archive both directories, and save the build and extension list next to the archive:

    Terminal window
    STAMP=$(date +%Y%m%d)
    mkdir -p ~/cursor-backups
    tar -czf ~/cursor-backups/cursor-$STAMP.tgz \
    -C ~ ".cursor" "Library/Application Support/Cursor"
    cursor --version > ~/cursor-backups/version-$STAMP.txt
    cursor --list-extensions --show-versions > ~/cursor-backups/extensions-$STAMP.txt

    The archive can be large. Keep the last two and delete older ones. On Windows PowerShell 5.1, Compress-Archive cannot store a file over 2 GB, and the application data directory holds large caches; use PowerShell 7, use tar -czf (tar.exe ships with Windows 10 and later), or leave out the Cache and CachedData folders.

  3. Commit the project’s Cursor configuration. Rules, skills, hooks and .cursor/mcp.json belong in the repository, where git diff shows any change an update or a teammate makes. If git status shows uncommitted files under .cursor/, commit them on a branch now.

  4. Record the agent baseline with the prompt below, in a fresh chat on the current build.

Read the baseline once, before you update. A rule, server or tool that is missing today is not the update’s fault, and you want to know that now rather than tomorrow.

Update Cursor and prove the new build works

Section titled “Update Cursor and prove the new build works”

With a baseline on disk, the update itself is the easy part: check for updates from the Command Palette (Check for Updates, or search the palette for “update”) or accept Cursor’s restart prompt. The work is proving the result, and the proof is a set of comparisons that either match or do not.

  1. Confirm the build changed: run cursor --version and compare the commit hash with the one you saved. The same hash means the update has not installed.

  2. Compare extensions with the saved list. Run this in the backup directory:

    Terminal window
    diff extensions-YYYYMMDD.txt <(cursor --list-extensions --show-versions)

    Replace YYYYMMDD with the stamp from your backup. Version changes are normal. A line that starts with < (in PowerShell, marked <=) and has no matching > (=>) line for the same extension is an extension that is no longer installed. An installed extension that fails to activate does not show up in this diff; it shows up in the comparison prompt or in Developer: Show Running Extensions.

  3. Check that the project’s MCP file still parses. A malformed file is easy to miss in the UI, so check it from the terminal:

    Terminal window
    python3 -m json.tool .cursor/mcp.json > /dev/null && echo "mcp.json OK"
  4. Open a fresh chat on the new build and run the comparison prompt below.

  5. Run the project’s test command yourself, in your own terminal rather than through the agent, and check its exit code with echo $? (PowerShell: $LASTEXITCODE). Running it yourself means the key gate does not rest on the agent’s own report.

  6. Decide. The build passes when the commit changed, no extension is missing, mcp.json parses, your own test run exits 0, and every row of the comparison table says MATCH. Any difference goes to the rollback decision table before you work on anything else.

This is how you judge the update without reading the agent’s work: the table either says MATCH on every row or names the row that changed. The developer approves the update on their own machine. For a team, the tech lead signs off only after the canary tasks in the version-history routine also pass on the new build, and the same evidence-over-diffs idea is explained in reading evidence instead of code.

When should you roll back instead of fixing forward?

Section titled “When should you roll back instead of fixing forward?”

Roll back when the regression blocks work you must ship this week and has no quick fix. Fix forward when the cause is in your own configuration.

What the comparison showsMost likely causeDo this
A rule or skill is missing, and its file is unchanged in git diffThe new build reads rule or skill files differentlyRoll back, then check the file against Cursor’s current Rules or Skills documentation on a spare machine
An MCP server shows no tools, and its command fails in a terminal tooYour runtime (npx, uvx, docker) or its credentials, not CursorFix forward with MCP setup in Cursor
An MCP server shows no tools, but its command works in a terminalThe new buildRestart Cursor fully once; if it persists, roll back
Tests or lint fail on the same commit that passed in the baselineThe agent’s environment changed, for example the integrated terminal’s PATHCompare echo $PATH in Cursor’s terminal and in your own; roll back if you cannot fix it within 30 minutes
One extension no longer loadsThe extension, not CursorUpdate or disable that extension; roll back only if you cannot work without it

A rollback reinstalls the previous build and leaves your data where it is. You need the previous version number and commit hash, which you saved in version-YYYYMMDD.txt, and the matching SHA-256 hash. The Homebrew cask’s history on GitHub (Homebrew/homebrew-cask, file Casks/c/cursor.rb) lists the releases the cask was bumped to, each with its version, commit and a sha256 for macOS (Apple silicon and Intel) and Linux (x86_64 and aarch64), whether or not you installed through Homebrew. It may skip a release that came and went between bumps. On Windows, winget’s manifest carries the installer hash instead, but only for the releases winget packaged, and it packages far fewer than Cursor ships.

  1. Open the history of Casks/c/cursor.rb in the Homebrew cask repository and find the commit that set the version you saved. Copy the version, the commit hash, and the sha256 for your platform.

  2. Quit Cursor completely.

  3. Download the previous build, check its hash, and install it:

    Terminal window
    CURSOR_COMMIT=PREVIOUS_COMMIT_HASH
    ARCH=arm64 # x64 on Intel Macs
    curl -fL -o Cursor.zip \
    "https://downloads.cursor.com/production/$CURSOR_COMMIT/darwin/$ARCH/Cursor-darwin-$ARCH.zip"
    shasum -a 256 Cursor.zip # must equal the cask's sha256 for your arch
    unzip -q Cursor.zip
    mv /Applications/Cursor.app ~/cursor-backups/Cursor-bad.app
    mv Cursor.app /Applications/

    PREVIOUS_VERSION and PREVIOUS_COMMIT_HASH are the first two lines of your saved version-YYYYMMDD.txt. If the hash check prints a different value, stop and delete the download.

  4. Set "update.mode": "manual" before you start the old build, or Cursor installs the new build again at its next update check. Cursor is closed at this point, so edit the user settings file directly: ~/Library/Application Support/Cursor/User/settings.json on macOS, ~/.config/Cursor/User/settings.json on Linux, or %APPDATA%\Cursor\User\settings.json on Windows. Keep the installer, zip or AppImage of the build you rolled back to: if the hold does not take and Cursor updates itself again, you can undo that update the same way without searching the cask history a second time.

  5. Start Cursor, run cursor --version to confirm the old commit, and run the comparison prompt again. Every row should say MATCH.

  6. Restore the data archive only if the comparison still fails. Quit Cursor, move the current data directories aside, and extract the archive in their place, as the commands below do. Moving aside rather than deleting keeps anything you created after the backup.

    Terminal window
    mv "$HOME/Library/Application Support/Cursor" "$HOME/Library/Application Support/Cursor.pre-restore"
    mv ~/.cursor ~/.cursor.pre-restore
    tar -xzf ~/cursor-backups/cursor-YYYYMMDD.tgz -C ~

Remove the hold deliberately. Put a date on it, such as “until the next release that mentions the regression”, and set update.mode back when that release has passed the comparison on a spare machine.

What breaks during a Cursor update, and how do you recover?

Section titled “What breaks during a Cursor update, and how do you recover?”
  • The update downloads but never installs, or the restart prompt keeps returning. Quit Cursor completely, including any window on another desktop, and start it again. If the build does not change, install the current release from your package manager or from Cursor’s download page over the existing one. Your data directories are not touched.
  • Cursor runs hot after the update. Start it with extensions off: cursor --disable-extensions. If the load disappears, re-enable extensions one at a time, or run Help: Start Extension Bisect from the Command Palette. If it does not disappear, test a clean profile with cursor --user-data-dir /tmp/cursor-clean --extensions-dir /tmp/cursor-clean-ext, and report the build to Cursor if the clean profile is also slow.
  • The agent ignores a rule after the update. The comparison table names the missing rule. Check that its file is unchanged with git log -p -- .cursor/, then roll back or fix the file against Cursor’s current Rules documentation. Project rules in Cursor covers the file format.
  • MCP servers show no tools. Run the server’s command and args from mcp.json in a terminal. If that fails, the problem is the runtime or its credentials; MCP setup in Cursor has the fix for each symptom. If it works, quit and restart Cursor fully so it reloads mcp.json.
  • You rolled back and Cursor updated itself again. update.mode was not set before the old build started, or your build ignores it. Set it, reinstall the old build, and confirm with cursor --version after a full restart.
  • Chat history or workspace state is gone. Quit Cursor and restore the archive from step 6 of the rollback. Without an archive there is no copy to restore, which is the reason the backup runs before every update.
  • One teammate is fine and another is broken on the same build. Compare their cursor --version output and extension lists line by line. Different commit hashes mean they are not on the same build, whatever the version line says.

Post the report with both commit hashes. A report that names two builds and one reproduction is one the vendor can act on; “it broke after updating” is not.

How should a team roll out a Cursor update?

Section titled “How should a team roll out a Cursor update?”

A team adds one rule to everything above: nobody’s machine is the first to meet a new build during a deadline. The tech lead owns the routine, which is written out in the Cursor version history: read the release notes against committed config, run the canary tasks on the old and new builds, move one volunteer first, then everyone. This page supplies the parts that routine assumes: the per-machine baseline and comparison, and a rollback that works in minutes. Record the approved build as its commit hash in the team’s onboarding doc, because two machines can show the same version line and differ underneath.

The other tools handle updates differently: see Claude Code upgrade procedures and staying current with Codex.