- 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
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:
-
Find the running server process:
# Windows netstat -ano | findstr :8765 # Linux/macOS lsof -i :8765 -
Stop the server:
# Windows taskkill //F //PID <process_id> # Linux/macOS kill <process_id> -
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:
- Update all locale files - Add or update the translation key in both
en.jsonandru.json - Use consistent keys - Follow the existing key naming pattern (e.g.,
section.element,scripts.button.save) - Test both locales - Verify translations appear correctly by switching between EN/RU
Adding New Text
When adding new UI elements:
- Add the English text to
static/locales/en.json - Add the Russian translation to
static/locales/ru.json - In HTML: use
data-i18n="key.name"for text content - In HTML: use
data-i18n-placeholder="key.name"for input placeholders - In HTML: use
data-i18n-title="key.name"for title attributes - In JavaScript: use
t('key.name')ort('key.name', {param: value})for dynamic text
Adding New Locales
To add support for a new language:
- Create
media_server/static/locales/{lang_code}.json(copy fromen.json) - Translate all strings to the new language
- Add the language code to
supportedLocalesarray inindex.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:
git tag v0.3.0→ CI reads the tag- Build scripts stamp
pyproject.tomlwith the clean version viased pip installbakes the version into package metadataimportlib.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:
- Lint —
ruff check media_server/(rules: E, F, I, W) - Test —
pytest --tb=short -q
Release workflow at .gitea/workflows/release.yml triggers on v* tags:
- Create release — Gitea release via REST API (detects pre-release from tag)
- Build Windows — cross-builds on Linux using embedded Python + NSIS installer
- Upload assets — portable ZIP + installer
.exeattached 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_nodesorquery_graphinstead of Grep - Understanding impact:
get_impact_radiusinstead of manually tracing imports - Code review:
detect_changes+get_review_contextinstead of reading entire files - Finding relationships:
query_graphwith 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
- The graph auto-updates on file changes (via hooks).
- Use
detect_changesfor code review. - Use
get_affected_flowsto understand impact. - Use
query_graphpattern="tests_for" to check coverage.