[project] name = "talkthrough-mcp" version = "0.4.1" description = "Local MCP server: turn screen recordings into transcript, exact frames, OCR and wall-clock evidence for coding agents." readme = "README.md" authors = [ { name = "korovin-aa97", email = "korovin.aa97@gmail.com" } ] license = "MIT" license-files = ["LICENSE"] requires-python = ">=3.11,<3.14" keywords = [ "mcp", "mcp server", "model-context-protocol", "screen-recording", "video", "transcription", "whisper", "ocr", "feedback", ] classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Operating System :: MacOS", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Topic :: Multimedia :: Video", "Topic :: Software Development :: Quality Assurance", "Typing :: Typed", ] dependencies = [ "faster-whisper>=1.2.1", # 2.1.1 is the first stable 2.x release tested by the v0.3 port. Keep the # next-major bound explicit: MCP 3.x may change the public server contract. "mcp>=2.1.1,<3", "pillow>=12.3.0", "rapidocr>=3.9.1", "static-ffmpeg>=3.0", ] [project.optional-dependencies] # >=1.13.4: 1.13.1 fixed a native SIGSEGV in clustering (k2-fsa/sherpa-onnx#3563), # 1.13.4 fixed split-package metadata under uv (#3690) — we install via uvx. diarization = ["sherpa-onnx>=1.13.4"] # URL ingestion (process_url). yt-dlp's [default] extra carries yt-dlp-ejs, # the bundled JavaScript components YouTube extraction needs, and [deno] # pulls the Deno runtime from PyPI so one install command is enough — no # system JavaScript runtime, no manual downloader install. 2026.8.19 is the # release-tested version. Direct HTTPS media URLs need no extra (httpx is # already a dependency of the MCP SDK). url = ["yt-dlp[default,deno]>=2026.8.19"] # sherpa-onnx 1.13.4's *sdist* PKG-INFO (Metadata-Version 2.1) omits its # sherpa-onnx-core dependency; uv's universal resolution reads the sdist # metadata, so without this override the lock silently drops the core # package (which carries the vendored ONNX Runtime) and `import sherpa_onnx` # fails. Platform-specific installs (pip, uvx) read the wheel metadata and # are unaffected. Version-scoped on purpose: a future sherpa bump must # revisit this pin (core is ABI-locked `==` to the bindings). [[tool.uv.dependency-metadata]] name = "sherpa-onnx" version = "1.13.4" requires-dist = ["sherpa-onnx-core==1.13.4"] [project.urls] Homepage = "https://github.com/korovin-aa97/talkthrough-mcp" Repository = "https://github.com/korovin-aa97/talkthrough-mcp" Issues = "https://github.com/korovin-aa97/talkthrough-mcp/issues" Changelog = "https://github.com/korovin-aa97/talkthrough-mcp/blob/main/CHANGELOG.md" [project.scripts] talkthrough-mcp = "talkthrough_mcp.cli:main" [build-system] requires = ["uv_build>=0.11.28,<0.12.0"] build-backend = "uv_build" [tool.ruff] line-length = 100 target-version = "py311" src = ["src", "tests"] # untracked local staging for demo-GIF sources — not part of the package extend-exclude = ["media-staging"] [tool.ruff.lint] select = ["E", "F", "W", "I", "UP", "B", "SIM", "RUF"] [tool.ruff.lint.per-file-ignores] # captured ffmpeg stderr sample lines are long by nature "tests/unit/test_frames.py" = ["E501"] # tool-description example one-liners are allowed up to 120 chars by the # guidance contract (enforced in tests/unit/test_guidance.py); Cyrillic # ё/е examples are the point of the search guidance "src/talkthrough_mcp/guidance.py" = ["E501", "RUF001"] # chart copy uses typographic en dashes on purpose "scripts/make_benchmark_chart.py" = ["RUF001"] # generator templates carry one-line skill descriptions and markdown tables "scripts/gen_integrations.py" = ["E501"] # Cyrillic ё→е folding literals and RU sample strings are the FEATURE here # (#16 search normalization + vocabulary-echo trimming), not lookalike typos "src/talkthrough_mcp/core/manifest.py" = ["RUF001", "RUF002"] "src/talkthrough_mcp/core/stt.py" = ["RUF001", "RUF002"] "tests/unit/test_manifest.py" = ["RUF001", "RUF003"] # RU/DE/ES/FR name plates and UI chrome are the corpus under test "tests/unit/test_findings_032_names.py" = ["RUF001"] "tests/unit/test_stt_echo.py" = ["RUF001", "RUF002"] "tests/integration/fixture_facts.py" = ["RUF003"] "tests/integration/test_pipeline_integration.py" = ["RUF001", "RUF002"] [tool.mypy] # 3.12 (the pinned dev/CI interpreter): transitive numpy stubs use py3.12 # `type` statements; ruff target-version py311 keeps the syntax floor honest. python_version = "3.12" strict = true warn_unreachable = true show_error_codes = true [[tool.mypy.overrides]] module = [ "faster_whisper.*", "static_ffmpeg.*", "rapidocr.*", "rapidocr_onnxruntime.*", "sherpa_onnx.*", "yt_dlp.*", "deno.*", ] ignore_missing_imports = true [tool.pytest.ini_options] testpaths = ["tests"] pythonpath = ["."] timeout = 900 addopts = "-ra" [dependency-groups] dev = [ "mypy>=2.2.0", "pytest>=9.1.1", "pytest-timeout>=2.4.0", "ruff>=0.15.21", ]