uv: Das Python-Tool, das du über MCP-Server kennengelernt hast

Julian | Jun 12, 2026 min read

Du richtest gerade einen MCP-Server für Claude Code oder Claude Desktop ein, kopierst eine Config aus der Doku – und stolperst über diesen Befehl:

{
  "mcpServers": {
    "fetch": {
      "command": "uvx",
      "args": ["mcp-server-fetch"]
    }
  }
}

uvx. Kein pip install, kein python -m venv, kein „erst mal die requirements.txt anlegen". Einfach uvx irgendwas, und es läuft.

Wenn du aus der Java- oder Node-Welt kommst, kennst du das Gefühl: Python-Tooling hatte über Jahre den Ruf, fummelig zu sein. Virtualenvs, die man vergisst zu aktivieren. Drei verschiedene Wege, Pakete zu installieren, je nachdem welches Tutorial du gerade liest. Genau dieses Problem hat uv sich vorgenommen – und ist dabei so gut geworden, dass es inzwischen quasi der Standard-Weg ist, Python-basierte MCP-Server zu starten.

Schauen wir uns an, was uv eigentlich ist, warum es bei MCP-Setups überall auftaucht, und wie du es in deinen eigenen Python-Projekten einsetzt.

Was ist uv überhaupt?

uv ist ein Python-Paket- und Projektmanager, entwickelt von Astral – dem Team hinter Ruff, dem Linter, der in den letzten Jahren ähnlich schnell die Python-Welt erobert hat. Geschrieben ist uv in Rust, und genau das ist der Hauptgrund für seinen Erfolg: Geschwindigkeit, die in der Python-Welt bisher unüblich war.

Das eigentlich Bemerkenswerte an uv ist aber nicht nur die Performance, sondern dass es ein einziges Tool für Aufgaben ist, für die du vorher fünf verschiedene Tools gebraucht hast:

AufgabeBisheriges ToolMit uv
Pakete installierenpipuv pip / uv add
Virtuelle Umgebungenvenv / virtualenvuv venv (automatisch)
Dependency-Lockingpip-toolsuv lock
Projekt- & Dependency-Managementpoetryuv (pyproject.toml)
Tools isoliert ausführenpipxuvx
Python-Versionen verwaltenpyenvuv python

Du installierst also nicht mehr fünf Tools mit fünf unterschiedlichen Konfigurationsdateien und fünf unterschiedlichen mentalen Modellen – du installierst uv.

Zum Geschwindigkeitsversprechen: uv löst Dependency-Installationen typischerweise 10- bis 100-mal schneller auf als pip. Das liegt an drei Dingen zusammen: der Rust-Implementierung, einem globalen Cache (ein Paket wird systemweit nur einmal heruntergeladen, danach nur noch verlinkt) und massiver Parallelisierung beim Download. Bei einem kleinen Projekt merkst du das kaum – aber bei einem Monorepo mit mehreren Services und hunderten Dependencies ist der Unterschied zwischen “Kaffee holen” und “weiterarbeiten”.

Warum uvx der Star bei MCP-Servern ist

Wenn du schon mal einen Node-basierten MCP-Server eingerichtet hast, kennst du npx: Statt ein Paket global zu installieren, lädst du es einmal herunter, führst es aus und lässt den Rest hinter dir. Genau das ist uvx für die Python-Welt – nur dass es vorher schlicht kein gutes Äquivalent dazu gab.

Schau dir noch mal die Config von oben an:

{
  "mcpServers": {
    "fetch": {
      "command": "uvx",
      "args": ["mcp-server-fetch"]
    }
  }
}

Was hier im Hintergrund passiert: uvx mcp-server-fetch lädt das Paket mcp-server-fetch aus PyPI, baut dafür eine ephemere, isolierte Umgebung (gecached, damit der zweite Start sofort geht) und führt das darin enthaltene Kommando aus. Du brauchst keine global installierten Python-Pakete, keine Versionskonflikte zwischen verschiedenen MCP-Servern, kein „welches Python ist das gerade".

Der Unterschied zum klassischen Weg

Ohne uv sähe das Setup für denselben MCP-Server so aus:

# Anti-Pattern: der klassische Weg
git clone https://github.com/example/mcp-server-fetch
cd mcp-server-fetch
python -m venv .venv
source .venv/bin/activate
pip install -e .
python -m mcp_server_fetch

Sechs Schritte, ein aktiviertes venv, das du nicht vergessen darfst – und in der Claude-Config müsstest du den vollen Pfad zum Python-Interpreter im venv hinterlegen. Fehleranfällig, und auf einem zweiten Rechner fängst du wieder bei null an.

Mit uvx wird daraus eine Zeile, die überall gleich funktioniert – ob auf deinem Mac, in einem Docker-Container oder auf dem Rechner eines Kollegen:

uvx mcp-server-fetch

Genau diese Eigenschaft – ein Befehl, keine Vorbereitung, reproduzierbar – ist der Grund, warum praktisch jede MCP-Server-Dokumentation inzwischen uvx als empfohlenen Weg zeigt. MCP-Server sind kleine, oft kurzlebige Tools, die du ausprobierst, austauschst oder nur gelegentlich brauchst. Genau für dieses Nutzungsmuster ist uvx gebaut.

uv im Projekt-Alltag: Anti-Pattern vs. Best Practice

Anti-Pattern: der venv-pip-requirements-Tanz

So sieht der klassische Start eines Python-Projekts aus – wahrscheinlich kennst du das genau so:

mkdir my-project && cd my-project
python -m venv .venv
source .venv/bin/activate          # unter Windows: .venv\Scripts\activate
pip install requests pandas
pip freeze > requirements.txt
python main.py

Das Problem ist nicht, dass das nicht funktioniert. Das Problem ist alles, was schiefgehen kann, ohne dass du es merkst:

  • Du vergisst source .venv/bin/activate in einem neuen Terminal-Tab und installierst Pakete plötzlich global.
  • pip freeze > requirements.txt schreibt auch alle transitiven Dependencies mit exakten Versionen rein – ein Update von pandas reicht, und die Datei ist ein einziger Diff-Krieg.
  • requirements.txt unterscheidet nicht zwischen “das brauche ich zum Entwickeln” (Tests, Linter) und “das brauche ich in Produktion”.

Best Practice: uv init, uv add, uv run

Mit uv sieht derselbe Start so aus:

uv init my-project
cd my-project
uv add requests pandas
uv run main.py

Was hier passiert:

  1. uv init legt ein neues Projekt an – mit pyproject.toml, .python-version und einer Grundstruktur. Kein leeres Verzeichnis, sondern ein Projekt mit Standardkonfiguration.
  2. uv add requests pandas installiert die Pakete und trägt sie in die pyproject.toml ein und schreibt eine uv.lock-Datei mit exakt aufgelösten Versionen – automatisch, in einem Schritt.
  3. uv run main.py führt das Skript in der projekteigenen virtuellen Umgebung aus. Du musst nichts aktivieren – uv erkennt das .venv-Verzeichnis im Projekt und nutzt es einfach.

Die pyproject.toml sieht danach so aus:

[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
    "requests>=2.32.0",
    "pandas>=2.2.0",
]

Dev-Dependencies (Tests, Linter) trennst du sauber ab:

uv add --dev pytest ruff

Das Killer-Feature: Skripte mit Inline-Dependencies

Richtig praktisch wird es bei einzelnen Skripten, die du mal eben ausführen willst, ohne ein ganzes Projekt aufzusetzen. uv unterstützt PEP 723 – Dependencies werden direkt im Skript als Kommentar deklariert:

# script.py
# /// script
# dependencies = [
#   "requests<3",
#   "rich",
# ]
# ///

import requests
from rich import print

resp = requests.get("https://api.github.com/repos/astral-sh/uv")
print(resp.json())

Ausführen mit:

uv run script.py

uv liest den Kommentarblock, baut sich im Hintergrund eine passende, gecachte Umgebung und führt das Skript aus – ganz ohne venv, ohne pip install, ohne dass du irgendetwas vorbereiten musst. Genau dasselbe Prinzip, das uvx für MCP-Server nutzt, nur eben für deine eigenen Skripte.

Pro-Tipps / Warnungen

Pro-Tipp: uv.lock gehört ins Git-Repo

Die uv.lock-Datei ist das Äquivalent zu package-lock.json (npm) oder poetry.lock. Sie fixiert nicht nur die Versionen deiner direkten Dependencies, sondern der gesamten Abhängigkeitskette – exakt, inklusive Hashes. Committest du sie mit, installiert uv sync auf jedem Rechner (und in jeder CI-Pipeline) garantiert dieselben Versionen. Lässt du sie weg, verlierst du genau den Vorteil, den du mit uv gerade gewonnen hast: reproduzierbare Builds.

Pro-Tipp: Migration ohne Big Bang – das uv pip-Interface

Du musst nicht von heute auf morgen dein ganzes Projekt auf pyproject.toml und uv add umstellen. uv bringt ein Drop-in-kompatibles pip-Interface mit:

uv venv
uv pip install -r requirements.txt
uv pip compile requirements.in -o requirements.txt

Das ist exakt dieselbe Syntax wie bei pip, läuft aber mit der uv-Geschwindigkeit. Damit kannst du bestehende Projekte schrittweise umstellen – erst die Installation beschleunigen, später (wenn überhaupt) auf den vollen Projekt-Workflow mit uv add/uv run wechseln.

Achtung: Python-Versionen nicht doppelt verwalten

uv kann Python-Versionen selbst installieren und verwalten – uv python install 3.12 lädt eine eigenständige Python-Version herunter, unabhängig von deinem System-Python. In Kombination mit einer .python-version-Datei im Projekt sorgt das dafür, dass uv run immer die richtige Version nutzt.

Die Falle: Wenn du zusätzlich noch pyenv aktiv hast, konkurrieren beide Tools um dieselbe Aufgabe – und du verbringst deine Zeit damit, herauszufinden, welches Tool gerade “gewonnen” hat. Entscheide dich für eines. Für neue Projekte ist uv python der pragmatischere Weg, weil es direkt in den Rest des Workflows integriert ist.

Fazit

uv ist eines dieser Tools, die du nicht aktiv suchst – du stolperst darüber, weil sie sich leise in den Workflows etablieren, die du sowieso schon nutzt. Bei dir war es uvx in einer MCP-Server-Config. Bei jemand anderem ist es vielleicht ein GitHub-Repo, dessen README plötzlich uv sync statt pip install -r requirements.txt zeigt.

Das eigentlich Interessante daran: uv löst keine neuen Probleme. Pakete installieren, virtuelle Umgebungen verwalten, Versionen pinnen – das konnte Python alles vorher schon. uv macht es nur so einfach und schnell, dass die ganzen kleinen Workarounds, an die du dich gewöhnt hattest, plötzlich überflüssig sind. Das ist kein Sprung nach vorne, sondern eher das Aufräumen eines Werkzeugkastens, der über 15 Jahre gewachsen ist.

Wenn dein nächstes Python-Projekt ansteht – oder du das nächste Mal requirements.txt tippst – probier stattdessen uv init und uv add. Der Umstieg dauert keine fünf Minuten, und du wirst den venv-Tanz nicht vermissen.