Fresh stdio JSON-RPC MCP server wrapping the frozen /api/v1 surface,
superseding the closed read-only PR #76. 26 read tools (six families +
search/all-items & search/artists discovery) and cautious-write CRUD:
collections (incl. idempotent membership adds for #487), smart collections,
schedules, playouts, channels (create/update/delete/reset), and a
Jellyfin-focused media-source sync/scan slice. Writes gated behind
ERSATZTV_ALLOW_WRITES (default false, runtime-enforced).
Security baseline carried forward from PR #76/#289: read-only backstop,
JSON-RPC DoS guards + bounded stdin reader, per-request CTS over
headers+body, response-size cap, arg validation vs InputSchema,
reverse-proxy prefix preservation. Machine-key auth (X-Api-Key,
CSRF-exempt). If-Match/ETag round-trip for the one replace-all PUT that
honors it.
Cold-review fixes folded in:
- HIGH: reject control chars (CR/LF) in the ifMatch value before it reaches
TryAddWithoutValidation — SocketsHttpHandler writes it verbatim, so a
crafted value could smuggle headers onto the X-Api-Key request.
- Cache the empty-args JsonDocument (no per-call pooled-doc leak).
- Accept explicit JSON null for optional fields so a nullable API field
(e.g. dailyRebuildTime) can be cleared as documented.
Deferred (documented): the ~40-field replace-list writes and redesign
workflow tools (#63-#68).
Docs: docs/mcp.md, docs/README.md index, docs/decisions.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add ErsatzTV.Architecture.Tests asserting the solution's layering, so a
"just import it here" violation fails the build instead of eroding the
architecture over time:
- Core must not depend on Application/Infrastructure*/Scanner, nor on
EF Core / Pomelo / Microsoft.Data.Sqlite / Dapper.
- FFmpeg (lowest layer) must not depend on any other ErsatzTV layer.
- Application must not depend on the concrete Infrastructure.Sqlite/.MySql
providers (only the Infrastructure abstraction).
- Infrastructure must not depend on Application or the concrete providers.
Uses NetArchTest.eNhancedEdition — the maintained fork; the original
NetArchTest.Rules is unmaintained since 2021 and its older Mono.Cecil
doesn't reliably parse .NET 10 assemblies. Runs via the existing `dotnet
test` in CI. Rules verified with a negative control (a known-true
dependency asserted forbidden fails as expected — so they're not vacuous).
Refs #12
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Add select all controls to media lists
* Refine select-all helper and add coverage
* Adjust select-all button alignment
* Tighten select-all helper semantics
* Allow tests to access internal members
* Rename select-all helper and avoid shift tracking
* Simplify select-all reset helper
* Keep pager centered and move select-all right
* Add missing div
* create test project for main app; move and rename new tests
* remove core => main app reference
* cleanup unused imports
* Fix button behavior when the screen is small
* update changelog
---------
Co-authored-by: Jason Dove <1695733+jasongdove@users.noreply.github.com>
* start to stream directly from plex
* update metadata and statistics with one plex api call
* stream movies from plex
* scanning bug fix; update changelog
* start moving local scans to separate process
* send progress updates to main process
* move scanners and tests
* simplify dependencies; sync search index
* commit search index more often when scanning
* support forced scan and cancellation
* use scanner process for plex libraries
* update changelog
* update dockerfiles
* fix search index for local folder scanning
* rework plex scanners
* rework scanner handlers
* emby works again
* sync jellyfin
* cleanup
* update build
* update changelog
* remove scanner dependency in pr and artifacts workflows
* fix mac sed syntax
* fix pr build