--- title: versions sidebarTitle: versions --- # `fastmcp.utilities.versions` Version comparison utilities for component versioning. This module provides utilities for comparing component versions. Versions are strings that are first attempted to be parsed as PEP 440 versions (using the `packaging` library), falling back to lexicographic string comparison. Examples: - "1", "2", "10" → parsed as PEP 440, compared semantically (1 < 2 < 10) - "1.0", "2.0" → parsed as PEP 440 - "v1.0" → 'v' prefix stripped, parsed as "1.0" - "2025-01-15" → not valid PEP 440, compared as strings - None → sorts lowest (unversioned components) ## Functions ### `parse_version_key` ```python parse_version_key(version: str | None) -> VersionKey ``` Parse a version string into a sortable key. **Args:** - `version`: The version string, or None for unversioned. **Returns:** - A VersionKey suitable for sorting. ### `version_sort_key` ```python version_sort_key(component: FastMCPComponent) -> tuple[VersionKey, str] ``` Get a sort key for a component based on its version. Use with sorted() or max() to order components by version. The key is a `(VersionKey, raw)` tuple. The `VersionKey` orders by PEP 440 semantics (or lexicographically for non-PEP 440 strings); the raw version string is a deterministic tie-breaker so that two components whose versions are PEP 440-equivalent but spelled differently (e.g. `"1"` and `"1.0"`) are ordered reproducibly instead of by registration order. The raw tie-breaker only affects equivalent-version ties and never the primary version order, so range/equality matching (which uses `VersionKey` directly) is unchanged. **Args:** - `component`: The component to get a sort key for. **Returns:** - A deterministic, sortable `(VersionKey, raw)` tuple. ### `compare_versions` ```python compare_versions(a: str | None, b: str | None) -> int ``` Compare two version strings. **Args:** - `a`: First version string (or None). - `b`: Second version string (or None). **Returns:** - -1 if a < b, 0 if a == b, 1 if a > b. ### `is_version_greater` ```python is_version_greater(a: str | None, b: str | None) -> bool ``` Check if version a is greater than version b. **Args:** - `a`: First version string (or None). - `b`: Second version string (or None). **Returns:** - True if a > b, False otherwise. ### `max_version` ```python max_version(a: str | None, b: str | None) -> str | None ``` Return the greater of two versions. **Args:** - `a`: First version string (or None). - `b`: Second version string (or None). **Returns:** - The greater version, or None if both are None. ### `min_version` ```python min_version(a: str | None, b: str | None) -> str | None ``` Return the lesser of two versions. **Args:** - `a`: First version string (or None). - `b`: Second version string (or None). **Returns:** - The lesser version, or None if both are None. ### `dedupe_with_versions` ```python dedupe_with_versions(components: Sequence[C], key_fn: Callable[[C], str]) -> list[C] ``` Deduplicate components by key, keeping highest version. Groups components by key, selects the highest version from each group, and injects available versions into meta if any component is versioned. **Args:** - `components`: Sequence of components to deduplicate. - `key_fn`: Function to extract the grouping key from a component. **Returns:** - Deduplicated list with versions injected into meta. ## Classes ### `VersionSpec` Specification for filtering components by version. Used by transforms and providers to filter components to a specific version or version range. Unversioned components (version=None) always match any spec. **Args:** - `gte`: If set, only versions >= this value match. - `lt`: If set, only versions < this value match. - `eq`: If set, only this exact version matches (gte/lt ignored). Matching is PEP 440-normalized and `v`-prefix insensitive, so `eq="v1.0"` matches a component versioned `"1.0"`, and `eq="1.0"` matches `"1"` (PEP 440 treats `1` and `1.0` as the same version). If a server registers two PEP 440-equivalent spellings of the same component (e.g. both `"1"` and `"1.0"`), they are the same version under this spec; selection among them is deterministic (see `version_sort_key`), not registration-order dependent. **Methods:** #### `matches` ```python matches(self, version: str | None) -> bool ``` Check if a version matches this spec. **Args:** - `version`: The version to check, or None for unversioned. - `match_none`: Whether unversioned (None) components match. Defaults to True for backward compatibility with retrieval operations. Set to False when filtering (e.g., enable/disable) to exclude unversioned components from version-specific rules. **Returns:** - True if the version matches the spec. #### `intersect` ```python intersect(self, other: VersionSpec | None) -> VersionSpec ``` Return a spec that satisfies both this spec and other. Used by transforms to combine caller constraints with filter constraints. For example, if a VersionFilter has lt="3.0" and caller requests eq="1.0", the intersection validates "1.0" is in range and returns the exact spec. **Args:** - `other`: Another spec to intersect with, or None. **Returns:** - A VersionSpec that matches only versions satisfying both specs. ### `VersionKey` A comparable version key that handles None, PEP 440 versions, and strings. Comparison order: 1. None (unversioned) sorts lowest 2. PEP 440 versions sort by semantic version order 3. Invalid versions (strings) sort lexicographically 4. When comparing PEP 440 vs string, PEP 440 comes first