Skip to content

solidworks_mcp.setup.launcher

solidworks_mcp.setup.launcher

The command a client config runs to start this server.

It is always an absolute path, so the config works no matter where the client starts it or what its PATH is. Usually it is the launcher in the environment setup itself runs from. When that environment is a temporary one in uv's cache (uvx solidworks-mcp-python setup), it is uvx instead, because the cache folder disappears when uv cleans it.

Attributes

PACKAGE module-attribute

PACKAGE = 'solidworks-mcp-python'

_UV_ARCHIVE module-attribute

_UV_ARCHIVE = re.compile('archive-v\\d+', re.IGNORECASE)

Functions:

find_uvx

find_uvx(uv: str | None = None, which: Callable[[str], str | None] = shutil.which) -> str | None

Find the uvx launcher, by absolute path.

Parameters:

Name Type Description Default
uv str | None

The uv executable; defaults to the UV variable uv sets for the programs it runs.

None
which Callable[[str], str | None]

PATH lookup, replaceable in tests.

which

Returns:

Type Description
str | None

uvx beside uv if it is there, else on the PATH, else None.

Source code in src/solidworks_mcp/setup/launcher.py
def find_uvx(
    uv: str | None = None, which: Callable[[str], str | None] = shutil.which
) -> str | None:
    """Find the ``uvx`` launcher, by absolute path.

    Args:
        uv: The uv executable; defaults to the ``UV`` variable uv sets for
            the programs it runs.
        which: PATH lookup, replaceable in tests.

    Returns:
        ``uvx`` beside uv if it is there, else on the PATH, else ``None``.
    """
    uv = uv if uv is not None else os.environ.get("UV")
    if uv:
        for name in ("uvx.exe", "uvx"):
            beside = Path(uv).parent / name
            if beside.is_file():
                return str(beside)
    return which("uvx")

in_uv_cache

in_uv_cache(python: str) -> bool

Whether an interpreter lives in a temporary environment in uv's cache.

uv tool install environments (under uv\tools) and project .venv folders are persistent and don't count.

Parameters:

Name Type Description Default
python str

The interpreter's path.

required

Returns:

Type Description
bool

True when a cache folder holds an archive-v<n> folder on the

bool

path to it.

Source code in src/solidworks_mcp/setup/launcher.py
def in_uv_cache(python: str) -> bool:
    """Whether an interpreter lives in a temporary environment in uv's cache.

    ``uv tool install`` environments (under ``uv\\tools``) and project
    ``.venv`` folders are persistent and don't count.

    Args:
        python: The interpreter's path.

    Returns:
        True when a ``cache`` folder holds an ``archive-v<n>`` folder on the
        path to it.
    """
    parts = [part.lower() for part in Path(python).parts]
    return any(
        _UV_ARCHIVE.fullmatch(part) and "cache" in parts[:index]
        for index, part in enumerate(parts)
    )

server_command

server_command(mock: bool = False, year: int | None = None, python: str | None = None, lasting: bool = True, uvx_finder: Callable[[], str | None] = find_uvx) -> tuple[str, list[str]]

The command and arguments that start this server.

Parameters:

Name Type Description Default
mock bool

Add --mock, so the server answers without SolidWorks.

False
year int | None

Add --year <year>, the SolidWorks release the server works with; ignored with mock.

None
python str | None

The interpreter to look beside; defaults to sys.executable.

None
lasting bool

Return a command that outlives a temporary uv environment. False gives the launcher that runs right now, which is what the start-up check needs.

True
uvx_finder Callable[[], str | None]

Finds uvx, replaceable in tests.

find_uvx

Returns:

Type Description
str

(command, args): uvx running this package when lasting and

list[str]

the interpreter is in uv's cache; otherwise the solidworks-mcp

tuple[str, list[str]]

console script in the environment's scripts folder or, without one,

tuple[str, list[str]]

this Python running the server module.

Source code in src/solidworks_mcp/setup/launcher.py
def server_command(
    mock: bool = False,
    year: int | None = None,
    python: str | None = None,
    lasting: bool = True,
    uvx_finder: Callable[[], str | None] = find_uvx,
) -> tuple[str, list[str]]:
    """The command and arguments that start this server.

    Args:
        mock: Add ``--mock``, so the server answers without SolidWorks.
        year: Add ``--year <year>``, the SolidWorks release the server works
            with; ignored with ``mock``.
        python: The interpreter to look beside; defaults to ``sys.executable``.
        lasting: Return a command that outlives a temporary uv environment.
            ``False`` gives the launcher that runs right now, which is what
            the start-up check needs.
        uvx_finder: Finds ``uvx``, replaceable in tests.

    Returns:
        ``(command, args)``: ``uvx`` running this package when ``lasting`` and
        the interpreter is in uv's cache; otherwise the ``solidworks-mcp``
        console script in the environment's scripts folder or, without one,
        this Python running the server module.
    """
    python = python or sys.executable
    if mock:
        flags = ["--mock"]
    else:
        flags = ["--year", str(year)] if year else []
    if lasting and in_uv_cache(python):
        uvx = uvx_finder()
        if uvx:
            return uvx, [PACKAGE, *flags]
    scripts = Path(python).parent
    # `.exe` on Windows; the bare name elsewhere.
    for name in ("solidworks-mcp.exe", "solidworks-mcp"):
        launcher = scripts / name
        if launcher.is_file():
            return str(launcher), flags
    return python, ["-m", "solidworks_mcp.server", *flags]