Files
media-player-server/CLAUDE.md
T
alexei.dolgolyov e7372b0ccb
Lint & Test / test (push) Successful in 11s
chore: wire up code-review-graph MCP server
- Add .mcp.json registering code-review-graph (uvx, stdio)
- Document the MCP tools in CLAUDE.md so the assistant prefers
  graph queries over Grep/Glob/Read for structural exploration
- Ignore .code-review-graph/ index directory
2026-05-01 11:28:22 +03:00

7.7 KiB

Media Server - Development Guide

Overview

Standalone REST API server (FastAPI) for controlling system-wide media playback on Windows, Linux, macOS, and Android.

Running the Server

Manual Start

python -m media_server.main

Auto-Start on Boot (Windows Task Scheduler)

Run in Administrator PowerShell from the media-server directory:

.\media_server\service\install_task_windows.ps1

To remove the scheduled task:

Unregister-ScheduledTask -TaskName "MediaServer" -Confirm:$false

Development Workflow

Server Restart After Code Changes

CRITICAL: When making changes to backend code (Python files, API routes, service logic), the media server MUST be restarted for changes to take effect.

When to restart:

  • Changes to any Python files (*.py) in the media_server directory
  • Changes to API endpoints, routes, or request/response models
  • Changes to service logic, callbacks, or script execution
  • Changes to configuration handling or startup logic

When restart is NOT needed:

  • Static file changes (*.html, *.css, *.json) - browser refresh is enough
  • README or documentation updates
  • Changes to install/service scripts (only affects new installations)

Frontend Rebuild After JS Changes

CRITICAL: The frontend is bundled via esbuild into static/dist/app.bundle.js. After modifying ANY JavaScript file in media_server/static/js/, you MUST run:

npm run build

Raw JS file edits have NO effect until the bundle is rebuilt. After rebuilding, a browser hard-refresh (Ctrl+Shift+R) is sufficient — no server restart needed.

How to restart during development:

  1. Find the running server process:

    # Windows
    netstat -ano | findstr :8765
    
    # Linux/macOS
    lsof -i :8765
    
  2. Stop the server:

    # Windows
    taskkill //F //PID <process_id>
    
    # Linux/macOS
    kill <process_id>
    
  3. Start the server again:

    python -m media_server.main
    

Best Practice: Always restart the server immediately after committing backend changes to verify they work correctly before pushing.

CRITICAL Always check acccessibility of WebUI after server restart to ensure that server has started without issues

Configuration

Copy config.example.yaml to config.yaml and customize.

The API token is generated on first run and displayed in the console output.

Default port: 8765

Internationalization (i18n)

The Web UI supports multiple languages with translations stored in separate JSON files.

Locale Files

Translation files are located in:

  • media_server/static/locales/en.json - English (default)
  • media_server/static/locales/ru.json - Russian

Maintaining Translations

IMPORTANT: When adding or modifying user-facing text in the Web UI:

  1. Update all locale files - Add or update the translation key in both en.json and ru.json
  2. Use consistent keys - Follow the existing key naming pattern (e.g., section.element, scripts.button.save)
  3. Test both locales - Verify translations appear correctly by switching between EN/RU

Adding New Text

When adding new UI elements:

  1. Add the English text to static/locales/en.json
  2. Add the Russian translation to static/locales/ru.json
  3. In HTML: use data-i18n="key.name" for text content
  4. In HTML: use data-i18n-placeholder="key.name" for input placeholders
  5. In HTML: use data-i18n-title="key.name" for title attributes
  6. In JavaScript: use t('key.name') or t('key.name', {param: value}) for dynamic text

Adding New Locales

To add support for a new language:

  1. Create media_server/static/locales/{lang_code}.json (copy from en.json)
  2. Translate all strings to the new language
  3. Add the language code to supportedLocales array in index.html

Versioning

pyproject.toml is the single source of truth for the version string.

At runtime, media_server/__init__.py reads the version via importlib.metadata.version() — no manual syncing needed.

Version flow:

  1. git tag v0.3.0 → CI reads the tag
  2. Build scripts stamp pyproject.toml with the clean version via sed
  3. pip install bakes the version into package metadata
  4. importlib.metadata.version("media-server") reads it at runtime

When bumping the version for a new release, only pyproject.toml needs to be updated.

Important: After making any changes, always ask the user if the version needs to be incremented.

CI/CD

Gitea Actions workflow at .gitea/workflows/test.yml runs on every push/PR to master:

  1. Lintruff check media_server/ (rules: E, F, I, W)
  2. Testpytest --tb=short -q

Release workflow at .gitea/workflows/release.yml triggers on v* tags:

  1. Create release — Gitea release via REST API (detects pre-release from tag)
  2. Build Windows — cross-builds on Linux using embedded Python + NSIS installer
  3. Upload assets — portable ZIP + installer .exe attached to the release

Releasing

# Stable release
git tag v1.0.0 && git push origin v1.0.0

# Pre-release
git tag v1.1.0-alpha.1 && git push origin v1.1.0-alpha.1

Installer

The NSIS installer (installer.nsi) installs to %LOCALAPPDATA%\Media Server (no admin required) with optional:

  • Desktop shortcut
  • Start with Windows (Startup folder shortcut, runs hidden via VBS)

Uninstall preserves config.yaml (user data).

Reference: gitea-python-ci-cd.md

IMPORTANT: When modifying CI/CD workflows, installer.nsi, or build scripts (build-dist-*.sh), always fetch and consult the guide above first to ensure changes stay in sync with established patterns.

Before Pushing

Ensure CI will pass locally:

ruff check media_server/
pytest --tb=short -q

Git Rules

  • ALWAYS ask for user approval before committing and pushing changes.
  • When pushing, always push to all remotes: git push origin master && git push github master

MCP Tools: code-review-graph

IMPORTANT: This project has a knowledge graph. ALWAYS use the code-review-graph MCP tools BEFORE using Grep/Glob/Read to explore the codebase. The graph is faster, cheaper (fewer tokens), and gives you structural context (callers, dependents, test coverage) that file scanning cannot.

When to use graph tools FIRST

  • Exploring code: semantic_search_nodes or query_graph instead of Grep
  • Understanding impact: get_impact_radius instead of manually tracing imports
  • Code review: detect_changes + get_review_context instead of reading entire files
  • Finding relationships: query_graph with callers_of/callees_of/imports_of/tests_for
  • Architecture questions: get_architecture_overview + list_communities

Fall back to Grep/Glob/Read only when the graph doesn't cover what you need.

Key Tools

Tool Use when
detect_changes Reviewing code changes — gives risk-scored analysis
get_review_context Need source snippets for review — token-efficient
get_impact_radius Understanding blast radius of a change
get_affected_flows Finding which execution paths are impacted
query_graph Tracing callers, callees, imports, tests, dependencies
semantic_search_nodes Finding functions/classes by name or keyword
get_architecture_overview Understanding high-level codebase structure
refactor_tool Planning renames, finding dead code

Workflow

  1. The graph auto-updates on file changes (via hooks).
  2. Use detect_changes for code review.
  3. Use get_affected_flows to understand impact.
  4. Use query_graph pattern="tests_for" to check coverage.