Skip to content

stremio-mcp 0.2.0

Pre-release
Pre-release

Choose a tag to compare

@netixc netixc released this 21 Jul 23:08
97682b3

Added

  • A bounded raw TCP preflight now separates a masked adb denial from a real network failure. When adb connect reports the TV as unreachable or the network as ambiguous but one short probe of the configured endpoint connects — a single attempt, no bytes written, two-second cap — the failure is reported as local_network_denied with guidance to grant adb Local Network access on macOS or reuse an ADB server started from a permitted GUI terminal. A failed probe keeps the original diagnosis, because the probing process may itself be denied, and the probe never runs an ADB server lifecycle command.

Security

  • TMDB credentials can no longer reach logs or returned errors. Every network failure is reported as a category, host, and status code, and a redaction filter strips configured credentials, secret-bearing query parameters, and Authorization values from every log record, traceback, and tool result — including the request lines emitted by the underlying HTTP library.
  • A TMDB v4 read access token is now sent as an Authorization: Bearer header so it never appears in a URL. A legacy v3 API key has no header form and is still sent as a query parameter, which is why no failure path reports a prepared URL.
  • Stremio library reads return a typed outcome that distinguishes found, an authoritative not found, and an error. add and remove abort without writing on any read error, identity mismatch, duplicate row, unrequested extra row, or content-type mismatch, so a transient failure can no longer be read as absence and overwrite existing watch state. Writes abort when the write request itself fails and when verification cannot confirm identity, type, removal state, and watch state.

Changed

  • The mcp requirement is now >=1.28.1,<2, so installs stay on the stable v1 SDK line until a deliberate v2 migration.
  • ADB failures now retain bounded categories such as unreachable, ambiguous network, unauthorized, offline, timeout, and transport failure through the controller and tool responses. User-facing guidance and routine logs omit device endpoints, raw ADB output, credentials, URLs, and command payloads. Failed device operations invalidate stale connection state, connection retries are serialized and bounded, and volume changes no longer report success when the shell command fails.
  • macOS ADB troubleshooting now identifies adb as the Local Network-permission binary, documents starting the shared server from a permitted GUI terminal for localhost clients, and forbids automated ADB server lifecycle management.
  • All HTTP work now runs on one lifecycle-managed async httpx client with explicit connect, read, write, and pool timeouts, a bounded response body, a bounded connection pool, and cancellation support. Previously TMDB requests were synchronous with no timeout and blocked the whole MCP event loop, freezing unrelated device controls.
  • Automatic searches resolve external IDs concurrently under a bounded semaphore instead of issuing up to ten serial requests.
  • Network bounds are configurable through STREMIO_MCP_* environment variables; an unparsable or out-of-range value is reported by variable name, without its value, and replaced with the default.
  • library list, library check, library search, library continue, and library-sourced play now report an unavailable library separately from an empty one.
  • TMDBClient and StremioAPIClient methods are now coroutines and take a shared AsyncHTTPClient. This is a breaking change for anyone importing those classes directly; it is required to move network I/O off the event loop.
  • search reports a TMDB outage as an error instead of as "No results found". An automatic search whose movie or TV half fails returns the other half's results with an explicit (partial results — …) note.
  • An unfollowed redirect is reported as its own redirect category instead of being decoded and misreported as malformed JSON, and an httpx stream failure is now categorized as a connection failure rather than escaping the typed error contract.
  • A Stremio API-level error now also reports the server-generated numeric error code, so an expired or revoked auth key is diagnosable without echoing any part of the request.
  • Write verification compares only the state keys this module actually writes, so a server-side addition to an untouched field no longer reports a successful mutation as failed. Any intended key that is missing or different is still a failure.

Fixed

  • ANDROID_TV_PORT is now read through the same bounded integer configuration helper as other numeric settings. Empty, quoted, nonnumeric, and out-of-range values no longer crash module import; they fall back to the default 5555 and report only the variable name, never the raw value.
  • tv_control playback stop now reports success as a post-condition instead of as ADB accepting KEYCODE_MEDIA_STOP, which Stremio/VLC commonly ignores while still playing. The server tries a media-session stop, then pause plus back, then a bounded am force-stop com.stremio.one, verifies after each step, and fails closed with the reason when the session still reports active playback or its state cannot be read.
  • playback_status no longer reports healthy playback for a stale or Exo-error media session that still claims PLAYING. A claimed playing state must be corroborated by a started AudioTrack for the session owner; otherwise it is reported as stalled and the raw position is kept instead of being extrapolated. Parsing is confined to Stremio's own session block, previously unhandled states such as error, buffering, and connecting are no longer reported as stopped, and an unreadable ADB dump is reported as a device failure rather than as no playback.

Removed

  • The requests dependency, replaced by httpx (already a transitive MCP dependency).
  • StremioAPIClient.get_library_item, get_library, get_continue_watching, and search_library. They collapsed an error back into None or [], reintroducing the ambiguity the typed reads exist to remove; use read_library_item, read_library, read_continue_watching, and read_library_search.