build: pin mcp SDK to the stable v1 line and document Android TV wireless debugging requirements - #23
Merged
Merged
Conversation
Bound the official mcp dependency to >=1.28.1,<2 so a future v2 stable release cannot be selected accidentally. Keep the lock on mcp 1.28.1. Document Android 13+ Wireless Debugging for TV, a durable Platform Tools floor with a preference for current releases, separate pair/connect ports, and why native adb remains the intentional transport.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Ship the captain-approved safe modernization for netixc/stremio-mcp: pin the official Python MCP SDK to the stable v1 line with an explicit upper bound (mcp>=1.28.1,<2), refresh uv.lock while keeping resolved mcp 1.28.1, and document current Android TV Wireless Debugging requirements (Android 13+ for TV, Platform Tools wireless-era minimum with preference for current stable, separate pairing vs connection ports, and that native Platform Tools adb remains intentional because pure-Python ADB clients lack modern TLS/STLS plus shell diagnostics).
Deliberate constraints from the modernization audit and captain decisions: keep native adb, stdio, low-level MCP Server, httpx, and setuptools unchanged; do not add Android TV Remote, Cast, Appium, FastMCP, MCP v2, or any new runtime dependency (Android TV Remote experiment was declined); do not include the separate ANDROID_TV_PORT fix, version bump to 0.1.1, changelog release conversion, tag, PyPI publish, or MCP Registry publish in this PR. Include independently checkable proof via a unit test that parses pyproject.toml and proves the MCP requirement accepts 1.28.1 and rejects 2.0.0, with genuine fail-before/pass-after against the bound.
What Changed
mcpdependency inpyproject.tomlfrom>=1.28.1to>=1.28.1,<2and refresheduv.lockaccordingly, so installs stay on the stable v1 SDK line until a deliberate v2 migration; the resolved version is unchanged at 1.28.1 and no new runtime dependency was added. Recorded underChangedinCHANGELOG.md(no release conversion or version bump).ReleaseMetadataTestsintests/test_stremio_mcp.pythat parse the[project]dependency list and assert the requirement accepts 1.28.1 and rejects 2.0.0. The parsing is regex/text-based rather thantomllibso the module still imports on Python 3.10, which is in the CI matrix.README.mdandAGENTS.md: Android 13+ for official TV wireless debugging, a Platform Tools floor of 30.0.0+ with a preference for the latest stable, the separate (often ephemeral) pairing vs connection ports, and the rationale for keeping native Platform Toolsadb— pure-Python ADB clients lack modern TLS (STLS) and shell diagnostics.The transport, MCP server style,
httpxusage, and build backend are unchanged. Pipeline checks pass, includinguv sync --locked, the 100-test unit suite,compileall, anduv build; testing also covered a fail-before/pass-after run of the new pin test against a temporarily reverted bound.Risk Assessment
✅ Low: The change is a bounded dependency upper bound plus documentation and one self-contained metadata test, all matching the stated intent, with the previously reported Python 3.10 import break now fixed and no runtime code touched.
Testing
Ran the full CI-equivalent chain (locked sync, 100 unit tests, compileall, build) plus targeted evidence work: I evaluated the built wheel's Requires-Dist with
packagingto show the pin accepts mcp 1.28.1 and rejects 2.0.0 exactly as an installer would, confirmed uv.lock still resolves 1.28.1, demonstrated genuine fail-before/pass-after for the new pyproject-parsing test by reverting and restoring the upper bound, drove a real MCP stdio session against the installed console script to show the pinned SDK still serves initialize/tools/list/tools/call, and captured a rendered screenshot of the updated README Android TV Wireless Debugging documentation. Everything passed and the diff stays inside the declared scope; build/cache artifacts were cleaned from the worktree.Evidence: Installer-level proof the MCP pin accepts 1.28.1 and rejects 2.0.0
# Built wheel: dist/stremio_mcp_server-0.1.0-py3-none-any.whl # Requires-Dist as an installer (pip/uv) sees it: Requires-Dist: httpx>=0.28.1 Requires-Dist: mcp<2,>=1.28.1 # Evaluating specifier '<2,>=1.28.1' for package 'mcp': mcp 1.28.1 -> ACCEPTED mcp 1.99.0 -> ACCEPTED mcp 2.0.0 -> REJECTED mcp 2.1.0 -> REJECTED # Locked resolution still pins the v1 baseline: uv.lock resolved mcp == 1.28.1 OK: v1 accepted, 2.x rejected, lock pinned at 1.28.1Evidence: Fail-before / pass-after for the new MCP pin test
=== FAIL-BEFORE: revert the bound to the pre-change 'mcp>=1.28.1' === AssertionError: 'mcp>=1.28.1' != 'mcp>=1.28.1,<2' FAILED (failures=1) === PASS-AFTER: restore 'mcp>=1.28.1,<2' === Ran 1 test in 0.001s OKEvidence: Live MCP stdio session against the shipped server with the pinned SDK
$ .venv/bin/stremio-mcp (installed mcp SDK == 1.28.1) <- initialize: {"name": "stremio-mcp", "version": "1.28.1"} protocolVersion=2025-06-18 <- tools/list: 5 tools - search: Search for movies or TV shows. Returns results with IMDb IDs. - play: Play movies or TV episodes. Use 'query' to search by title, or 'imdb_id' - library: Read or mutate the Stremio library. Add/remove require an explicit IMDb - tv_control: Control Android TV. volume: up/down/mute/set. playback: play/pause/toggl - playback_status: Get current playback status. Returns app, title, state (playing/paused/s -> tools/call search (no TMDB key configured) <- Error: TMDB_API_KEY not configured./tmp/no-mistakes-evidence/01KY31C3FBD9A7CJTQ89T5YSPG/readme-android-tv-requirements.png)Evidence: Rendered README sections (GFM HTML source for the screenshot)
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
tests/test_stremio_mcp.py:9-import tomllibis unconditional at module scope, buttomllibwas added in Python 3.11 whilerequires-python = ">=3.10"and the CI matrix includes 3.10 (.github/workflows/ci.yml:22). On Python 3.10 the import raises ModuleNotFoundError before any test class is collected, so the ENTIRE tests/test_stremio_mcp.py module fails to load — not just the new MCP-pin test.tomliis not a declared dependency and is absent from uv.lock, so no fallback exists. Fix by parsing the dependency without tomllib (the file is read as text anyway) or by guarding the import with a version check plus a text-based fallback; addingtomlifor <3.11 would require a dev dependency and lock refresh.tests/test_stremio_mcp.py:783-_version_tuple/_cmp_version/_requirement_containshand-roll ~50 lines of partial PEP 440 semantics that are only exercised by one assertion set, and they diverge from real resolver behaviour (pre-release suffixes are truncated, so>=1.28.1would be reported as accepting1.28.1rc1;_requirement_containssilently returns True when no version clause is found at all). Sincetest_mcp_dependency_stays_on_stable_v1already asserts the exact requirement string, the semantic bound checks can be expressed far more simply (e.g. assert the parsed clause set is{('>=', '1.28.1'), ('<', '2')}) without a bespoke comparator.tests/test_stremio_mcp.py:859-self.assertEqual(requirement, "mcp>=1.28.1,<2")makes the test fail on semantically identical rewrites such asmcp>=1.28.1,<2.0ormcp >= 1.28.1, < 2. That strictness is defensible as a deliberate pin, but it means the bound-evaluation assertions below it can never independently fail; flagging so the tradeoff is a conscious choice.README.md:33- The requirements list hardcodes "37.x at the time of writing" as the current Platform Tools stable release. This is an unverifiable-offline, fast-ageing claim that will silently become wrong; consider dropping the specific version and keeping only the 30.0.0+ floor plus "prefer the latest stable from the Platform Tools page", which is the durable guidance the intent asks for.🔧 Fix: Make MCP pin test 3.10-safe and drop stale adb version claim
1 info still open:
tests/test_stremio_mcp.py:769-_project_dependenciesscans the[project]table with regexes instead of a TOML parser — a reasonable tradeoff given the 3.10 floor and the no-new-dependency constraint. Worth knowing the one edge it has:re.findall(r"[\"']([^\"']+)[\"']", ...)also picks up quoted strings on commented-out lines inside the dependencies array, so a# "mcp>=1.0",line would produce a secondmcpmatch and trip theexpected one 'mcp' dependencyAssertionError. It fails loudly rather than silently, so no action is needed unless the array grows comments.✅ **Test** - passed
✅ No issues found.
uv sync --locked— lockfile consistent with pyproject (34 packages resolved, no drift)uv run --locked python -m unittest discover -s tests -v— 100 tests, all passuv run --locked python -m compileall -q src testsuv build— sdist + wheel builtManual resolver-level proof: parsedRequires-Distfrom the built wheel METADATA and evaluated it withpackaging→ mcp 1.28.1/1.99.0 ACCEPTED, 2.0.0/2.1.0 REJECTED; asserted uv.lock still resolves mcp == 1.28.1Fail-before/pass-after: temporarily reverted pyproject tomcp>=1.28.1, rantests.test_stremio_mcp.ReleaseMetadataTests.test_mcp_dependency_stays_on_stable_v1(FAILED), restored the bound and re-ran (OK); worktree restored cleanEnd-to-end MCP stdio session against the installed.venv/bin/stremio-mcpconsole script:initializehandshake,notifications/initialized,tools/list, andtools/call searchwith the pinned SDK (mcp 1.28.1)Rendered the changed README## Requirements→## Pair and connect the TVsections via the GitHub markdown API and captured a full-page screenshot to verify the Android 13+, Platform Tools 30.0.0+/latest-stable, pairing-vs-connection-port, and native-adb TLS/STLS rationale copyScope audit of the diff: 5 files touched, no new runtime dependency, no FastMCP/Appium/Android TV Remote/Cast, transport/backend unchanged, version still 0.1.0, no changelog release conversion, tag, or publish✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.