How to configure Cursor for a uv project
Cursor is a fork of VS Code, so most Python tooling configuration works the same way. The key difference is Cursor’s AI agent, which needs explicit rules to use uv instead of pip. This guide covers both the editor setup and the agent configuration.
Required extensions
Cursor uses the Open VSX Registry instead of the VS Code Marketplace. The following extensions are available on Open VSX and can be installed from Cursor’s extensions panel:
The Python extension handles interpreter selection and test discovery. It also installs the Python Debugger extension (debugpy) automatically. The Ruff extension provides linting and formatting.
Note
Cursor ships its own language server (anysphere.cursorpyright). If installing ms-python.python pulls in Pylance, disable Pylance to avoid conflicts with Cursor’s built-in language server.
Select the Python interpreter
uv creates a virtual environment in .venv/ at the root of your project. Cursor detects .venv directories automatically, so in most cases the interpreter is selected without manual configuration.
Run uv sync to ensure the virtual environment exists. Cursor should pick up the .venv interpreter within a few seconds. If it doesn’t, open the Command Palette (Ctrl+Shift+P / Cmd+Shift+P) and choose Python: Select Interpreter, then pick the interpreter inside .venv.
Tip
If Cursor shows import errors or unresolved modules after adding a dependency with uv add, run uv sync and then reload the window (Ctrl+Shift+P → Developer: Reload Window). The language server needs to re-index the environment.
Configure Ruff for formatting and linting
The Ruff extension replaces both a formatter (like Black) and a linter (like flake8). Cursor reads .vscode/settings.json for workspace settings, just like VS Code. Add these settings:
{
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports.ruff": "explicit"
}
}
}This formats Python files on save and organizes imports using Ruff. The extension reads your project’s ruff.toml or pyproject.toml settings automatically, so linting rules stay consistent between the editor and the command line.
Set up pytest
The Python extension can discover and run pytest tests from the Testing sidebar. Add these settings to .vscode/settings.json:
{
"python.testing.pytestEnabled": true,
"python.testing.unittestEnabled": false,
"python.testing.pytestArgs": ["tests"]
}After saving, open the Testing sidebar (beaker icon) and click Refresh Tests. Cursor will discover tests in your tests/ directory and let you run or debug them individually.
If pytest is a development dependency in your project (uv add --dev pytest), Cursor will find it in the .venv automatically.
Complete settings file
Here is a .vscode/settings.json that combines all the configurations above:
{
"python.testing.pytestEnabled": true,
"python.testing.unittestEnabled": false,
"python.testing.pytestArgs": ["tests"],
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports.ruff": "explicit"
}
}
}Commit this file to version control so everyone on the team gets the same formatter and test settings.
Configure Cursor’s AI agent to use uv
Cursor’s AI agent does not know about uv by default. Without explicit rules, it will suggest pip install and python commands instead of uv add and uv run. Create a .cursor/rules/ file to fix this.
For a step-by-step walkthrough, see How to configure Cursor rules to use uv.
Important
When Cursor’s agent runs terminal commands, it spawns a fresh shell that may not inherit your activated virtual environment. The agent rules should instruct it to use uv run for all Python execution rather than relying on venv activation.
Running Python files
The play button (Run Python File) runs your file with the selected interpreter directly. It does not wrap the command in uv run, so it bypasses uv’s dependency resolution for inline script metadata. For standalone scripts that declare their own dependencies with inline metadata, run them from the integrated terminal with uv run script.py instead of the play button.
For project code where dependencies are already installed in .venv via uv sync, the play button works fine.
Jupyter notebooks
To use Jupyter notebooks in Cursor with a uv project, add ipykernel as a development dependency:
uv add --dev ipykernelOpen a .ipynb file and Cursor will prompt you to select a kernel. Choose the Python interpreter from your .venv directory. If no kernel appears, run uv sync first to ensure ipykernel is installed in the environment.
Tip
Cursor’s AI features work better with plain .py files than .ipynb notebooks. If you want both notebook-style execution and full AI assistance, use # %% cell markers in .py files. Both Cursor and VS Code support running these as interactive cells.
For more details, see How to run a Jupyter notebook with uv.
Type checking with ty
ty is Astral’s type checker for Python, built by the same team behind uv and Ruff. The ty extension (astral-sh.ty) is available on Open VSX and provides type error diagnostics directly in the editor.
Note
ty is still early in development. Expect rough edges compared to mature type checkers like mypy or pyright.
Debugging
With the Python Debugger extension installed, open a Python file and run Python Debugger: Debug Python File from the Command Palette. For more control, create a .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
},
{
"name": "Python: Module",
"type": "debugpy",
"request": "launch",
"module": "your_package",
"console": "integratedTerminal"
}
]
}Replace your_package with your project’s package name. The debugger uses the interpreter from .venv, so it has access to all dependencies installed by uv.
Troubleshooting
“Import could not be resolved” warnings: Run uv sync to install all dependencies, then reload the Cursor window.
Wrong Python version: Check that uv python pin matches what Cursor shows in the status bar. If they differ, re-select the interpreter from the Command Palette.
Ruff settings not applied: The Ruff extension reads from pyproject.toml or ruff.toml in your project root. Run uv run ruff check . in the terminal to verify the rules match what the extension reports.
Language server conflicts: If you see duplicate diagnostics or unexpected errors, check whether both Pylance and Cursor’s built-in cursorpyright are active. Disable Pylance and keep the built-in language server.
Agent uses pip instead of uv: Set up .cursor/rules/ with uv instructions. See How to configure Cursor rules to use uv.
uv workspaces (monorepos): The language server does not fully understand uv workspace structures. Imports between workspace members may show false “unresolved import” warnings. As a workaround, add import paths to python.analysis.extraPaths in your workspace settings, or open each workspace member as a separate Cursor window.
Learn More
Get Python tooling updates
Subscribe to the newsletter