Skip to content

Instantly share code, notes, and snippets.

@joeblackwaslike
Last active July 5, 2025 12:39
Show Gist options
  • Save joeblackwaslike/752b26ce92e3699084e1ecfc790f74b2 to your computer and use it in GitHub Desktop.
Save joeblackwaslike/752b26ce92e3699084e1ecfc790f74b2 to your computer and use it in GitHub Desktop.
How to use python with the Cursor IDE

How to use python with the Cursor AI IDE

We are going to edit cursors settings to point to the microsoft extensions marketplace.

  1. Remove all extensions and exit Cursor.
  2. Locate your Cursor project.json file depending on your platform and open it.
    • On MacOS: /Applications/Cursor.app/Contents/Resources/app/product.json
    • On Windows: C:\Users\<user_name>\AppData\Local\Programs\cursor\resources\app\product.json
    • On Linux: /usr/lib/code/product.json
  3. Locate the object value for key extensionsGallery in the json document.

Contents of extensionsGallery key in product.json for Cursor

{
    "galleryId": "cursor",
    "serviceUrl": "https://marketplace.cursorapi.com/_apis/public/gallery",
    "itemUrl": "https://marketplace.cursorapi.com/items",
    "resourceUrlTemplate": "https://marketplace.cursorapi.com/{publisher}/{name}/{version}/{path}",
    "controlUrl": "",
    "recommendationsUrl": "",
    "nlsBaseUrl": "",
    "publisherUrl": ""
}
  1. Edit it to look like this:
{
    "galleryId": "cursor",
    "serviceUrl": "https://marketplace.visualstudio.com/_apis/public/gallery",
    "itemUrl": "https://marketplace.visualstudio.com/items",
    "resourceUrlTemplate": "https://{publisher}.vscode-unpkg.net/{publisher}/{name}/{version}/{path}",
    "controlUrl": "",
    "recommendationsUrl": "",
    "nlsBaseUrl": "",
    "publisherUrl": ""
}
  1. Reopen Cursor.app and install the following extensions:
    • ms-python.python
    • ms-python.vscode-pylance
    • ms-python.debugpy
  2. Make sure in your settings that python.languageServer is set to "Pylance"
  3. Re-sign Cursor.app (for MacOS)
codesign --force --deep --sign - /Applications/Cursor.app

Enjoy!

PS: you may need to goto your settings.json to remove any theme settings, because having a broken theme looks exactly like this same problem. In my case cursor had copied over my settings from vscode and they pointed to a theme that wasn't yet installed in cursor, removing and then setting the theme manually worked when I though for sure I had broken it again.

@kapis
Copy link

kapis commented Mar 10, 2025

The latest, 2025.3.1

@alexwilson1
Copy link

alexwilson1 commented Mar 19, 2025

Deleting the "extensionMaxVersions" block and then restarting Cursor completely would appear to bring all extensions to the latest versions too.

@lukaemon
Copy link

works!

@MarvinYang93
Copy link

MarvinYang93 commented Mar 24, 2025

2025-03-24 20:03:04.650 [info] [Info - 8:03:04 PM] (934244) Pylance language server 2024.8.1 (pyright version 1.1.373, commit ee424479) starting 2025-03-24 20:03:04.650 [info] [Info - 8:03:04 PM] (934244) Server root directory: file:///root/.cursor-server/extensions/ms-python.vscode-pylance-2024.8.1/dist 2025-03-24 20:03:04.652 [info] [Error - 8:03:04 PM] Server initialization failed. 2025-03-24 20:03:04.652 [info] Message: Request initialize failed with message: You may install and use any number of copies of the software only with Microsoft Visual Studio, Visual Studio for Mac, Visual Studio Code, Azure DevOps, Team Foundation Server, and successor Microsoft products and services (collectively, the “Visual Studio Products and Services”) to develop and test your applications. The software is licensed, not sold. This agreement only gives you some rights to use the software. Microsoft reserves all other rights. You may not: work around any technical limitations in the software that only allow you to use it in certain ways; reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the software, except and to the extent required by third party licensing terms governing use of certain open source components that may be included in the software; remove, minimize, block, or modify any notices of Microsoft or its suppliers in the software; use the software in any way that is against the law or to create or propagate malware; or share, publish, distribute, or lease the software (except for any distributable code, subject to the terms above), provide the software as a stand-alone offering for others to use, or transfer the software or this agreement to any third party.
But I still had this error and I still couldn't use pylance

@joeblackwaslike
Copy link
Author

Hm, when I open Cursor after editing the file i get: “Cursor.app” is damaged and can’t be opened. You should move it to the Bin. Tried reinstalling cursor before editing the product.json file but same result. Ideas?

This sounds like the app is protected with some kind of code signing, can you provide more context around your platform?

@lukaemon
Copy link

2025-03-24 20:03:04.650 [info] [Info - 8:03:04 PM] (934244) Pylance language server 2024.8.1 (pyright version 1.1.373, commit ee424479) starting 2025-03-24 20:03:04.650 [info] [Info - 8:03:04 PM] (934244) Server root directory: file:///root/.cursor-server/extensions/ms-python.vscode-pylance-2024.8.1/dist 2025-03-24 20:03:04.652 [info] [Error - 8:03:04 PM] Server initialization failed. 2025-03-24 20:03:04.652 [info] Message: Request initialize failed with message: You may install and use any number of copies of the software only with Microsoft Visual Studio, Visual Studio for Mac, Visual Studio Code, Azure DevOps, Team Foundation Server, and successor Microsoft products and services (collectively, the “Visual Studio Products and Services”) to develop and test your applications. The software is licensed, not sold. This agreement only gives you some rights to use the software. Microsoft reserves all other rights. You may not: work around any technical limitations in the software that only allow you to use it in certain ways; reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the software, except and to the extent required by third party licensing terms governing use of certain open source components that may be included in the software; remove, minimize, block, or modify any notices of Microsoft or its suppliers in the software; use the software in any way that is against the law or to create or propagate malware; or share, publish, distribute, or lease the software (except for any distributable code, subject to the terms above), provide the software as a stand-alone offering for others to use, or transfer the software or this agreement to any third party.

但是我依然遇到了这样的错误,无法载入

update cursor app could reset product.json so msft would detect cursor using its lang server, hence the error.

@realdimas
Copy link

I’ve seen quite a few macOS-related questions about Gatekeeper and System Integrity Protection (SIP) in this thread (“Cursor.app is damaged and can’t be opened. You should move it to the Trash.”).

Below are some helpful commands:

  • Check the code signatures on Cursor.app
    codesign -v -v --deep --strict /Applications/Cursor.app

  • Re-sign Cursor.app
    codesign --force --deep --sign - /Applications/Cursor.app

  • Check for the quarantine extended attribute
    xattr -p com.apple.quarantine /Applications/Cursor.app/Contents
    Any output other than No such xattr: com.apple.quarantine indicates that the application is quarantined.

  • Remove the quarantine extended attribute
    xattr -r -d com.apple.quarantine /Applications/Cursor.app

Also, note that right-clicking (or control-clicking) on an application in Finder and selecting “Open” is not the same as double-clicking it.
Using “Open” from the context menu lets you bypass Gatekeeper’s initial refusal, typically offering a button to force the application to open.
Often, apps that were prevented from opening will also appear in System SettingsPrivacy & SecuritySecurity section with a button “Open Anyway”.

@realdimas
Copy link

I too was disappointed that the Python language server shipped with Cursor does not support the unit test coverage UI.
However, I was able to get the current versions of Python extensions (Python, Python Debugger, and Pylance) to work in Cursor.

The workaround I’m using is as follows:

  • Edit package.json to increase the maxVersion of Python-related extensions
  • Disable auto-updates for Python-related extensions
  • Manually download the extension packages (the .VSIX files)
  • Drag and drop the extensions into Cursor’s Extensions tab

Here is a script I wrote to automate the package.json patching on macOS:
https://gist.github.com/realdimas/e58723564cfada8efd93adab6efb747c

It also re-signs the app’s code signature and removes the quarantine attribute (for convenience).

Note that updating the Cursor app will reset the version of the Python extensions, so you’ll need to reapply these changes (including the extension drag-and-drop).
I found it helpful to disable Cursor auto-updates (see instructions here: https://forum.cursor.com/t/how-do-i-prevent-automatic-updating/59637/10) and update Cursor manually instead.

@PhenomenaPh
Copy link

Hi!

Thank you for this guide!
I was wondering if there is any way to turn off the rewriting of product.json after each cursor update? It’s really annoying.

@Nivg
Copy link

Nivg commented Apr 6, 2025

Hi!

Thank you for this guide! I was wondering if there is any way to turn off the rewriting of product.json after each cursor update? It’s really annoying.

I just had the same question, each update I need to redo this process, the Cursor Python language support is broken!

@realdimas
Copy link

@PhenomenaPh, @Nivg – product.json is part of Cursor package.
You are hacking the internals of the app.
Each update override it – this is expected and no known workaround exist.
Understand that you generally want & need the updated product.json.
Its just that some keys in this file needs to be modified post-update to revive python extensions.

My approach: streamline the update of product.json file (see macOS script linked above that I use) and do upgrades manually (disable automatic upgrades) so that you can take care of "maintenance" tasks on your own time without disruption.

@Nivg
Copy link

Nivg commented Apr 6, 2025

@PhenomenaPh, @Nivg – product.json is part of Cursor package. You are hacking the internals of the app. Each update override it – this is expected and no known workaround exist. Understand that you generally want & need the updated product.json. Its just that some keys in this file needs to be modified post-update to revive python extensions.

My approach: streamline the update of product.json file (see macOS script linked above that I use) and do upgrades manually (disable automatic upgrades) so that you can take care of "maintenance" tasks on your own time without disruption.

It seems that in a devcontainer, where I set my extensions (and pylance is one of them), it's ignoring it and installing the cursoer pyright one all the time, do you have any idea about this issue?

Thanks!

@realdimas
Copy link

@Nivg locally, we fix this issue by patching product.json to shift away from the Cursor extension gallery and instead point to the Microsoft extension gallery.
We also bump the extension versions to the latest.
This allows us to install current and unmodified ms-python.python (and other) extensions via locally downloaded .VSIX files that don't depend on anysphere.pyright.

None of these local fixes have any effect on remote environments.

In remote environments, Cursor (VS Code) has its own product.json file and a modified version of the ms-python.python extension which declares a dependency on Cursor's Pyright (ID: anysphere.pyright) extension.

I didn't bother automating the rewrite of the remote product.json file, nor investigating how the patched ms-python.python extension gets there.

Instead, I use this workaround once per remote environment:

  1. Download Python extensions from Microsoft extension gallery as .VSIX files (matching the remote operating system and architecture).
  2. Drag-and-drop the .VSIX files into the Extensions tab's remote section.
  3. Reload window.
  4. Uninstall the Cursor Pyright extension.

I like to keep "Auto Update" checkbox unchecked to upgrade manually via .VSIX files instead.


Below are the direct download links to the current versions of Python extensions for linux-x64 and linux-arm64 architectures:

@Nivg
Copy link

Nivg commented Apr 9, 2025

@Nivg locally, we fix this issue by patching product.json to shift away from the Cursor extension gallery and instead point to the Microsoft extension gallery. We also bump the extension versions to the latest. This allows us to install current and unmodified ms-python.python (and other) extensions via locally downloaded .VSIX files that don't depend on anysphere.pyright.

None of these local fixes have any effect on remote environments.

In remote environments, Cursor (VS Code) has its own product.json file and a modified version of the ms-python.python extension which declares a dependency on Cursor's Pyright (ID: anysphere.pyright) extension.

I didn't bother automating the rewrite of the remote product.json file, nor investigating how the patched ms-python.python extension gets there.

Instead, I use this workaround once per remote environment:

  1. Download Python extensions from Microsoft extension gallery as .VSIX files (matching the remote operating system and architecture).
  2. Drag-and-drop the .VSIX files into the Extensions tab's remote section.
  3. Reload window.
  4. Uninstall the Cursor Pyright extension.

I like to keep "Auto Update" checkbox unchecked to upgrade manually via .VSIX files instead.

Below are the direct download links to the current versions of Python extensions for linux-x64 and linux-arm64 architectures:

Wow, many thanks for the very detailed explanation!

I wonder if with the new Microsoft enforcement rollout for using their extensions only in the official vscode, those workarounds won’t work anymore as well…

@gemnioo
Copy link

gemnioo commented May 8, 2025

does this method banned by $MSFT ?

[error] [Window] connect ECONNREFUSED 198.41.30.195:443: Error: connect ECONNREFUSED 198.41.30.195:443
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1611:16)
  "extensionsGallery": {
    "serviceUrl": "https://marketplace.visualstudio.com/_apis/public/gallery",
    "cacheUrl": "https://vscode.blob.core.windows.net/gallery/index",
    "itemUrl": "https://marketplace.visualstudio.com/items",
    "controlUrl": "",
    "recommendationsUrl": ""
  }

@realdimas
Copy link

@gemnioo 198.41.30.195 is eclipse.dev – doesn't seems relevant to the issues discussed in this gist:

$ host 198.41.30.195
195.30.41.198.in-addr.arpa domain name pointer eclipse.dev.

@gemnioo
Copy link

gemnioo commented May 9, 2025

@gemnioo 198.41.30.195 is eclipse.dev – doesn't seems relevant to the issues discussed in this gist:

$ host 198.41.30.195
195.30.41.198.in-addr.arpa domain name pointer eclipse.dev.

double checked Gemini not hallucinations

This error repeats multiple times throughout the logs.

    ECONNREFUSED: This is a standard network error code meaning the connection was actively refused by the server at the specified address and port. The server received the connection attempt but declined it.

    198.41.30.195: This is an IP address associated with Microsoft services, specifically related to the Visual Studio Marketplace (where VS Code/code-server fetches extensions from).

    443: This is the standard port for HTTPS (secure web traffic).

@realdimas
Copy link

2025.4.100 is the most recent Pylance extension that is compatible with the current Cursor (tested with 0.50 versions).
The extension can be installed by dragging and dropping the .vsix file into the Extensions tab in Cursor.

Direct download link to the .vsix extension package:
https://marketplace.visualstudio.com/_apis/public/gallery/publishers/ms-python/vsextensions/vscode-pylance/2025.4.100/vspackage

@Asap7772
Copy link

Thank you!

@charlie632
Copy link

I was able to install Pylance before, but somehow I broke my Cursor, so I had to do a clean installation, and none of the solutions are now working. I keep seeing the (Client) You may install and use any number of copies of the software only with Microsoft Visual Studio, Visual Studio for Mac, Visual Studio Code log on the Python Language Server output.

Has anyone found a new solution for this?

@canersnli
Copy link

I didn't see this warning but solutions mentioned above didn't work until I downgraded the cursor to 1.0

@realdimas
Copy link

Cursor just released v1.2.0 – a big upgrade to the upstream VSCode version used under the hood (v1.96.2 -> v1.99.3).
This is a welcome and long-awaited upgrade that improves support for newer extensions.

On the other hand, it breaks out-of-the-box support with Pylance 2025.4.1 (and 2025.4.100) builds.
These versions now (rightfully) detect that this isn't vanilla VSCode and bark with "You may install and use any number of copies of the software only with Microsoft Visual Studio...".

One way to address this issue is to simply downgrade to the most recent Cursor build that is still using VSCode v1.96.2, that is Cursor v1.1.7.
See unofficial links to the older Cursor builds at https://github.com/oslook/cursor-ai-downloads?tab=readme-ov-file#all-versions-download-table

Another way is to dial up the effort and start patching obfuscated Pylance code to coerce it into running on Cursor.

Earlier this year @caenrigen had shared a patch to Pylance v2025.4.1 that makes it work with VSCode forks (Cursor, Windsurf, etc.): VSCodium/vscodium#1641 (comment)

To recap:

  1. Download Pylance v2025.4.1 .vsix file.
  2. Unpack into a temporary folder
  3. Edit extension/dist/extension.bundle.js
  4. Remove the following string from the file:
    return(0x0,_0x302dc7[_0x1e5d1c(0x69a)])(_0x17bc9b[_0x1e5d1c(0x120)]),{'client':_0x5d8ccf,'start':()=>{const _0x751a33=_0x1e5d1c;return _0x2bfc9a['sendTelemetryEvent'](_0x1d90e3['EventName'][_0x751a33(0x48e)]),Promise[_0x751a33(0x60e)]();},'stop':()=>Promise[_0x1e5d1c(0x60e)](),'disposables':_0x22650a};
    
  5. Zip it back into a .vsix
  6. Install some other version of Pylance .vsix by drag-and-dropping it into the Extensions tab to "bust the cache" (skipping this might prevent the IDE from noticing patched content of the same-versioned extension)

Handy shell script (tested on macOS):

# Download Pylance v2025.4.1 (platform-independent)
wget https://marketplace.visualstudio.com/_apis/public/gallery/publishers/ms-python/vsextensions/vscode-pylance/2025.4.1/vspackage -O ms-python.vscode-pylance-2025.4.1.vsix

# Ungzip (not sure why it's gzipped on top of a zip, but that's what the server is returning regardless of the Accept-Encoding header value)
gunzip -c ms-python.vscode-pylance-2025.4.1.vsix > ms-python.vscode-pylance-2025.4.1.zip

# Unzip it into a folder
unzip -d ms-python.vscode-pylance-2025.4.1-patched ms-python.vscode-pylance-2025.4.1.zip

# Define the literal value to remove using a here-document
literal=$(cat <<'EOF'
return(0x0,_0x302dc7[_0x1e5d1c(0x69a)])(_0x17bc9b[_0x1e5d1c(0x120)]),{'client':_0x5d8ccf,'start':()=>{const _0x751a33=_0x1e5d1c;return _0x2bfc9a['sendTelemetryEvent'](_0x1d90e3['EventName'][_0x751a33(0x48e)]),Promise[_0x751a33(0x60e)]();},'stop':()=>Promise[_0x1e5d1c(0x60e)](),'disposables':_0x22650a};
EOF
)

# Calculate the length of the literal
length=${#literal}

# Create a replacement string of the same length (spaces)
replacement=$(printf '%*s' $length '')

# Replace the literal with spaces to preserve length with perl
perl -i -pe "s/\Q$literal\E/$replacement/g" ms-python.vscode-pylance-2025.4.1-patched/extension/dist/extension.bundle.js

# Package it back into a .vsix
(cd ms-python.vscode-pylance-2025.4.1-patched && zip -r ../ms-python.vscode-pylance-2025.4.1-patched.vsix .)

@qiangxinglin
Copy link

As of 2025/7/2, after upgrading Cursor to v1.2.0, the marketplace patch is not working anymore. Now I cannot search any extensions after patch the product.json.

@PhenomenaPh
Copy link

I guess we can change now a marketplace via vscode settings

image

@realdimas
Copy link

Custom extension gallery URLs can be set as of Cursor 1.1.3 (much like Windsurf).

https://forum.cursor.com/t/dbt-extension-not-visible-in-marketplace/107089/9

{
    // <...>
    "extensions.gallery.itemUrl": "https://marketplace.visualstudio.com/items",
    "extensions.gallery.serviceUrl": "https://marketplace.visualstudio.com/_apis/public/gallery",
    // <...>
}

Unfortunately, this hasn't been working in 1.2.0 (or 1.2.1):

For some strange reason, the extensions.gallery.itemUrl key is dimmed in the User Settings JSON, i.e., it seems to be unused (unlike in versions 1.1.3+ before the 1.2.0 release).

Setting both keys (and restarting Cursor) results in:

  • Extension gallery searches spin forever and return no results

Updating gallery keys in product.json results in:

  • Extension gallery searches return no results

It seems that the ability to point to a custom extension gallery has been broken since version 1.2.0.

@Ilyas-Malik
Copy link

Amazing @realdimas, your extension repackaging worked for me, no need to roll cursor back
Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment