Skip to content

Usage

You talk to your agent normally; it picks the tools. This page shows typical requests and the calls they lead to, which is also a good mental model when reviewing what the agent did.

“Create a new FastAPI app called api with Python 3.13 and add pytest as a dev dependency.”

uv_init { "path": "api", "python": "3.13" }
uv_add { "project_path": "api", "packages": ["fastapi[standard]"] }
uv_add { "project_path": "api", "packages": ["pytest"], "dev": true }

Use kind: "lib" for an installable library and kind: "script" for a single-file PEP 723 script.

“Set this repo up so I can run the tests.”

uv_project_info {}
uv_sync { "all_groups": true }
uv_run { "command": ["pytest", "-q"] }

uv_sync creates .venv, installs the right Python if needed, and makes the environment match uv.lock. uv_run syncs first too, so after the first sync the agent can simply run things.

“Upgrade httpx, then show me why urllib3 is installed.”

uv_sync { "upgrade_packages": ["httpx"] }
uv_tree { "packages": ["urllib3"], "invert": true }
RequestCall
Add to a groupuv_add { "packages": ["ruff"], "group": "lint" }
Add an optional extrauv_add { "packages": ["redis"], "optional": "cache" }
From a private indexuv_add { "packages": ["internal-lib"], "resolver": { "index": ["corp=https://pkgs.corp/simple"] } }
From gituv_add { "packages": ["git+https://github.com/org/repo"], "tag": "v1.2" }
Platform-specificuv_add { "packages": ["pywin32"], "marker": "sys_platform == 'win32'" }
Removeuv_remove { "packages": ["requests"] }
Upgrade everythinguv_lock { "upgrade": true } then uv_sync
What is outdated?uv_tree { "outdated": true, "depth": 1 }
Check for vulnerabilitiesuv_audit {} (and uv_tool_audit { "all": true } for installed tools)
Export for Dockeruv_export { "output_file": "requirements.txt", "no_dev": true }

The agent should never edit uv.lock by hand, and should prefer uv_add/uv_remove to editing pyproject.toml, so the lockfile and environment stay consistent.

“Run main.py with DEBUG=1.”

uv_run { "command": ["python", "main.py"], "env": { "DEBUG": "1" } }
  • A one-off extra package: "with_packages": ["rich"].
  • A script with inline metadata: "command": ["script.py"].
  • Without touching .venv: "isolated": true.
  • A long job: "timeout_seconds": 1800.

A non-zero exit status is reported as success: false with the real exit_code, so failing tests are easy to distinguish from a uv error (hint is set for the latter).

“Which packages are in this workspace, and where is the api package?”

uv_workspace_list { "paths": true }
uv_workspace_dir { "member": "api" }
uv_sync { "all_packages": true }

Most project tools take member to act on one workspace package (uv’s --package).

“Which Pythons do I have? Switch this project to 3.12.”

uv_python_list { "only_installed": true }
uv_python_install { "versions": ["3.12"] }
uv_python_pin { "version": "3.12" }
uv_sync {}

“Lint the project with ruff without adding it as a dependency.”

uv_tool_run { "command": ["ruff", "check", "."] }

This is uvx. Use from_package when the command and package names differ, for example { "command": ["http", "GET", "example.com"], "from_package": "httpie" }. To keep a tool installed permanently, use uv_tool_install.

“I’m getting ModuleNotFoundError, fix it.”

uv_diagnose {}
uv_repair {}

uv_diagnose returns findings such as uv.lock is out of date, .venv is missing, the environment’s interpreter is gone or installed packages have broken requirements, each with a suggested fix. uv_repair installs the required Python, recreates a broken .venv, re-locks and syncs (reinstalling when packages are inconsistent), then diagnoses again. It never edits pyproject.toml. Pass dry_run: true to see the plan first. If the missing module is not declared at all, the agent should add it with uv_add.

Plain virtual environments and requirements files

Section titled “Plain virtual environments and requirements files”

For projects that are not managed by uv:

uv_venv { "python": "3.12" }
uv_pip_install { "requirements": ["requirements.txt"] }
uv_pip_compile { "src_files": ["requirements.in"], "output_file": "requirements.txt", "universal": true }
uv_pip_sync { "src_files": ["requirements.txt"] }
uv_pip_list { "outdated": true }

“Build the package and publish it to TestPyPI.”

uv_build {}
uv_publish { "publish_url": "https://test.pypi.org/legacy/" }
uv_publish { "publish_url": "https://test.pypi.org/legacy/", "dry_run": false }

uv_publish is a dry run by default; the agent has to pass dry_run: false deliberately. Prefer trusted publishing from CI, or put UV_PUBLISH_TOKEN in the server’s env block, over pasting tokens into chat.

Tools that resolve packages (uv_add, uv_sync, uv_lock, uv_run, uv_export, uv_pip_install, uv_pip_compile, uv_tool_run, uv_tool_install) take a resolver object:

“Make sure this library still works with the oldest versions it claims to support.”

uv_lock { "resolver": { "resolution": "lowest-direct" } }
uv_sync {}
uv_run { "command": ["pytest", "-q"] }
FieldUse
resolutionhighest (default), lowest, lowest-direct
prereleaseallow, if-necessary, explicit, …
exclude_newerReproduce the world as of a date: "2025-01-31"
index, default_indexPrivate or extra indexes (name=url or a URL)
python_platformResolve for another OS (pip, sync, run, tool)
no_build, no_sources, offlineWheels only; ignore [tool.uv.sources]; cache only

Every tool accepts extra_args for options without a dedicated parameter. They are checked against the installed uv, so a typo fails fast with a suggestion instead of a confusing uv error:

uv_sync { "extra_args": ["--link-mode", "copy"] }

To find an option, ask uv_help. It returns every option of a command, its allowed values and environment variable, and whether to pass it as a parameter, in resolver, or in extra_args:

uv_help { "command": "pip compile", "search": "hash" }

And uv_command runs any uv subcommand, including ones added in uv releases newer than your uv-mcp:

uv_command { "args": ["self", "version", "--output-format", "json"] }