Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docker/pyproject.deps.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "mcp-plex"
version = "2.0.4"
version = "2.0.6"
requires-python = ">=3.11,<3.13"
dependencies = [
"fastmcp>=2.11.2",
Expand Down
5 changes: 5 additions & 0 deletions mcp_plex/loader/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,11 @@ async def load_media(
) -> None:
"""Orchestrate one or more runs of :func:`run`."""

if delay < 0:
raise ValueError(
f"Delay between runs must be non-negative; received {delay!r}"
)

while True:
await run(
plex_url=plex_url,
Expand Down
2 changes: 1 addition & 1 deletion mcp_plex/loader/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@
)
@click.option(
"--delay",
type=float,
type=click.FloatRange(min=0.0),
default=300.0,
show_default=True,
required=False,
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "mcp-plex"
version = "2.0.4"
version = "2.0.6"

description = "Plex-Oriented Model Context Protocol Server"
requires-python = ">=3.11,<3.13"
Expand Down
72 changes: 72 additions & 0 deletions tests/test_loader_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,33 @@ def test_cli_invalid_delay_value():
assert "Invalid value for '--delay'" in result.output


def test_cli_rejects_negative_delay(monkeypatch):
called = False

async def fake_load_media(*args, **kwargs):
nonlocal called
called = True

monkeypatch.setattr(loader_cli, "load_media", fake_load_media)

runner = CliRunner()
result = runner.invoke(
loader_cli.main,
["--delay", "-1", "--continuous"],
env={
"PLEX_URL": "http://localhost",
"PLEX_TOKEN": "token",
"TMDB_API_KEY": "key",
},
)

assert result.exit_code == 2
assert isinstance(result.exception, SystemExit)
assert result.exception.code == 2
assert "Invalid value for '--delay'" in result.output
assert not called


def test_run_requires_credentials(monkeypatch):
monkeypatch.setattr(loader, "PlexServer", object)

Expand Down Expand Up @@ -188,6 +215,51 @@ async def fake_run(**kwargs):
assert captured_kwargs["imdb_cache_path"] == imdb_cache


def test_load_media_rejects_negative_delay(monkeypatch, tmp_path):
async def fake_run(**kwargs):
raise AssertionError("run should not be called")

monkeypatch.setattr(loader, "run", fake_run)

with pytest.raises(
ValueError,
match="Delay between runs must be non-negative; received -1.0",
):
asyncio.run(
loader.load_media(
plex_url="http://localhost",
plex_token="token",
tmdb_api_key="key",
sample_dir=None,
qdrant_url=":memory:",
qdrant_api_key=None,
qdrant_host=None,
qdrant_port=6333,
qdrant_grpc_port=6334,
qdrant_https=False,
qdrant_prefer_grpc=False,
dense_model_name="dense",
sparse_model_name="sparse",
continuous=False,
delay=-1.0,
imdb_cache=tmp_path / "cache.json",
imdb_max_retries=3,
imdb_backoff=1.0,
imdb_requests_per_window=None,
imdb_window_seconds=1.0,
imdb_queue=tmp_path / "queue.json",
upsert_buffer_size=1,
plex_chunk_size=1,
enrichment_batch_size=1,
enrichment_workers=1,
qdrant_batch_size=1,
max_concurrent_upserts=1,
qdrant_retry_attempts=1,
qdrant_retry_backoff=1.0,
)
)


def test_loader_script_entrypoint(monkeypatch):
monkeypatch.setattr(sys, "argv", ["loader", "--help"])
module = sys.modules.pop("mcp_plex.loader.cli", None)
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.