How to configure Claude Code to use uv
Claude Code already reaches for uv add and uv run inside a project that has a pyproject.toml. Two things still go wrong: it falls back to python3 script.py in a directory with no project metadata, and it stops for an approval prompt on every uv command it does run.
Both are observed defaults rather than documented contracts, so both can shift under you. A project CLAUDE.md and a permission allowlist put the behavior in your repository instead.
Prerequisites
- Claude Code installed
- uv installed on your system
- A project directory. The allowlist check at the end adds a dependency, so run
uv initfirst if the directory has nopyproject.toml.
Pin uv as the only way to run Python
1. Write the uv rules into CLAUDE.md
Create CLAUDE.md in your project root with these rules. Claude Code loads the file at the start of every session, so the rules survive a restart and reach teammates who clone the repo.
# Python tooling
Use uv for every Python command in this project.
- Run scripts and tools with `uv run`, never bare `python` or `python3`.
- Add and remove dependencies with `uv add` and `uv remove`, never `pip install`.
- Sync and lock the environment with `uv sync` and `uv lock`.
- Run a one-off tool without adding it to the project: `uvx ruff check`.
- For a standalone script, use `uv run script.py` and add its dependencies with
`uv add --script script.py <package>`.2. Confirm Claude reaches for uv
Drop a throwaway script in the project root and ask Claude Code to run it:
echo 'print("hello")' > hello.py
claude -p "Run hello.py and show me the output."Claude runs uv run hello.py. In a directory that has neither pyproject.toml nor these rules, the same request gets python3 hello.py, which is the gap the file closes. Delete hello.py once you have seen the difference.
Stop the approval prompts
1. Allowlist the uv commands in .claude/settings.json
Create .claude/settings.json to pre-approve the uv commands and deny pip. Commit it so teammates inherit the same prompts, or keep the rules to yourself in .claude/settings.local.json.
{
"permissions": {
"allow": [
"Bash(uv run:*)",
"Bash(uv add:*)",
"Bash(uv remove:*)",
"Bash(uv sync:*)",
"Bash(uv lock:*)",
"Bash(uvx:*)"
],
"deny": [
"Bash(pip install:*)",
"Bash(pip3 install:*)",
"Bash(python -m pip install:*)",
"Bash(python3 -m pip install:*)"
]
}
}Every rule matches the literal start of a command, so Bash(uv run:*) covers uv run pytest, uv run ruff check, and uv run python. That same literal matching is why pip takes four deny rules: block only pip install and python -m pip install sails through, which is the spelling Claude picks once the short one is refused.
2. Accept the workspace trust dialog
Allow rules from a project you have not trusted are skipped, so the file you just wrote does nothing yet. Start an interactive session in the project root and accept the dialog before going further:
claudeclaude -p skips the trust dialog rather than showing it, so print mode alone can never get you past this point.
3. Confirm the allowlist changed what Claude does
Ask Claude Code to add a dependency and watch whether it needs you:
claude -p "Add idna as a dependency to this project."uv add idna runs unattended and idna appears under dependencies in pyproject.toml. Run uv remove idna to undo it.
If dependencies is unchanged and Claude reports that uv add idna needed approval, the rules did not load. Claude Code says so on startup:
Ignoring 6 permissions.allow entries from .claude/settings.json: this workspace has not been trusted.Repeat the trust step from the directory the message names. Trust is keyed to the git repository root, or to the directory you started Claude Code in when there is no repository, so accepting the dialog in a subdirectory leaves the root untrusted.
Apply the rules to every project
Personal defaults that follow you across repositories go in your user-level files, which Claude Code reads regardless of working directory.
~/.claude/CLAUDE.md
~/.claude/settings.jsonProject files win over user files, so a repository that needs different rules can override them.
Learn More
- Claude Code for Python: A Complete Guide for the wider setup this page fits into
- How to configure Claude Code to use virtual environments covers projects that use a plain
.venvinstead of uv - How to write Claude Code hooks for Python projects blocks bare
pythonandpipat the tool-call level - How to Set Up CLAUDE.md for a Python Project for a template covering the rest of your tooling
- How to use Python skills with Claude Code for procedures that load on demand instead of every session
- Claude Code permissions reference
- Claude Code project memory guide