Skip to content

How to configure Cursor for a uv project

This guide assumes you have a Python project managed with uv. If you haven’t created a project yet, see the project creation tutorial.

Cursor is a fork of VS Code, so most Python tooling configuration works the same way. The editor’s Python interpreter and the agent’s command environment need separate configuration. This guide covers both.

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:

  • Python (ms-python.python)
  • Ruff (charliermarsh.ruff)

The Python extension handles interpreterThe program that reads and executes Python code. When you run "python3 hello.py", python3 is the interpreter. selection and test discovery. Install the Python Debugger extension from Cursor’s extension panel for debugging. The Ruff extension provides linting and formatting.

Note

Cursor recommends Cursor Pyright for Python language support. Install it from Cursor’s extension panel and avoid enabling multiple Python language servers that report the same diagnostics.

Select the Python interpreter

uv creates a virtual environmentAn isolated folder where Python installs packages for one project, keeping them separate from other projects and your system Python. Learn more → 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 create .venv and install the project dependencies. After it completes, 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 unresolved imports after adding a dependency, confirm the selected interpreter is the project’s .venv. uv add already updates the project environment; selecting a different interpreter leaves the language server looking in the wrong 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 on manual saves 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 missing, install it with uv add --dev pytest. The --dev flag marks pytest as a development dependencyA package needed during development (testing, linting, formatting) that is not shipped to users of your project. Installed with the --dev flag. , keeping it out of production installs. uv updates pyproject.toml and uv.lock, then installs pytest in .venv.

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

Record the project’s commands in AGENTS.md or .cursor/rules/uv.mdc, including uv add for dependencies and uv run for Python execution. An editor interpreter selection does not tell the agent which commands to run.

For a step-by-step walkthrough, see How to configure Cursor rules to use uv.

Important

Use uv run in agent commands so they select the project’s environment without shell activation. uv run executes the command inside the project’s virtual environment, ensuring all dependencies are installed first. Cloud agents run in a separate environment and need their own uv installation and dependency setup.

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 ipykernel

uv updates pyproject.toml and uv.lock, then installs ipykernel in .venv.

Install the Jupyter extension, then open a .ipynb file and 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.

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.

Use the type checker configured by the project. If multiple type checker extensions are enabled, check for overlapping diagnostics.

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: Check the Ruff configuration selected for the file, including nested pyproject.toml, ruff.toml, or .ruff.toml files and editor overrides. If Ruff is installed as a project dependency, run uv run ruff check . to compare command-line diagnostics with the editor.

Language server conflicts: If diagnostics appear twice, check which Python language server and type checker extensions are enabled. Keep the combination configured by your project.

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): Select the workspace’s shared .venv and confirm the importing package declares its workspace dependencies. Do not add python.analysis.extraPaths to hide a missing dependency or an uninstalled package.

Last updated on